前言

作为前端开发者,在前后端分离的时代下,不能一天到晚追着后端的同学要接口调试,我们可以自己来 Mock 现在的打包工具或者框架基本都支持或者通过第三方插件支持了 Mock 数据的能力。对于写死的静态数据而言,我们可以使用 MockJS 来生成动态的数据,这至少这样看起来更逼真,而且更方便,可以通过 Mock 的表达式来生成指定格式及数量的 JSON 数据。

进入官网,映入眼帘的是这么几个大字,简洁明了、突出主题

image-20210706205749745

通过随机数据,模拟各种场景;不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据;支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等;支持支持扩展更多数据类型,支持自定义函数和正则

他的特性也在官网标注出来了

前后端分离、增加单元测试的真实性、开发无侵入、用法简单、方便扩展、数据类型丰富……

使用方法

我们先来看使用方法,下一节再看语法。使用Mockjs的时候可以有两种方式,页面直接引入、node环境使用,node中可以在文件中运行也可以跑一个nodeServer来提供数据。

页面

使用script标签引入mockjs

<script src="http://mockjs.com/dist/mock.js"></script>

然后就可以使用Mockjs进行数据模拟了,语法不要关心,后面会讲

<body>
  <script src="http://mockjs.com/dist/mock.js"></script>
  <script>
    let data = Mock.mock({
        "userInfo|4": [{
          "id|+1": 1,
          "name": "@cname",
          "ago|18-28": 25,
          "sex|1": ["男", "女"],
          "job|1": ["web", "UI", "python", "php"]
        }]
      })

      console.log(data);
  </script>
</body>

在浏览器打开控制台就可以看见模拟的数据了

image-20210707100324273

Node环境中使用

前端框架开发环境

这里我们以Vue开发环境为例,首先创建一个api.js,引入mockjs(需要npm安装依赖),导出模拟数据,这里可以将mock方法的第一个参数设置为一个url,可以实现上面官网提到的特性——拦截ajax请求

import {mock} from 'mockjs';

export default mock('http://localhost/a', {
  "userInfo|4": [{
    "id|+1": 1,
    "name": "@cname",
    "ago|18-28": 25,
    "sex|1": ["男", "女"],
    "job|1": ["web", "UI", "python", "php"]
  }]
})

然后在Vue组件中使用axios等工具来进行ajax请求

<script>
import './services/api1.js'
import axios from 'axios'

export default {
  name: 'App',
  created() {
    axios.get('http://localhost/a').then(res => {
      console.log(res);
    })
  }
}
</script>

执行npm run serve,打开控制台,这里看到通过拦截ajax生成的mock数据已经不再是一个简单的数据,而是被包装成了一个比较像请求响应的对象

image-20210707101240486

Node服务端

这里使用比较轻量化的服务端框架express来模拟服务端响应,在src目录下创建一个server目录,新建一个server.js文件,添加内容如下

let express = require('express');
let Mock = require('mockjs');

let app = express(); 

app.use('/user', function (req, res) {
  res.json(Mock.mock({
    'dataStatus': 200,
    "userInfo|4": [{
      "id|+1": 1,
      "name": "@cname",
      "ago|18-28": 25,
      "sex|1": ["男", "女"],
      "job|1": ["web", "UI", "python", "php"]
    }]
  }))
})

app.listen('8090', () => {
  console.log('监听端口 8090')
})

为了方便使用可以在package.json中添加启动脚本命令(非必须,可以不需要)

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "mock": "node src/server/server.js"
    // 为了方便修改内容可以使用nodemon(需要全局安装)
      // "mock": "nodemon src/server/server.js"
  },

启动服务端程序npm run mock,没有添加命令就直接使用node运行js文件

打开运行中的Vue页面,这时候会显示跨域错误

image-20210707102255172

解决办法也很简单,在服务端设置CORS即可,在server.js中添加这段代码,要在所有请求的最前面

app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

完成

image-20210707102606542

语法规则

mock中的数据模板由三部分构成:属性名、生成规则和属性值

// 属性名   name
// 生成规则 rule
// 属性值   value
'name|rule': value

生成规则有7种格式,对应的含义需要根据属性值类型来确定

  1. 'name|min-max': value
  2. 'name|count': value
  3. 'name|min-max.dmin-dmax': value
  4. 'name|min-max.dcount': value
  5. 'name|count.dmin-dmax': value
  6. 'name|count.dcount': value
  7. 'name|+step': value

string

使用之前的node服务端程序运行

  1. 'name|min-max': string

    通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max

  2. 'name|count': string

    通过重复 string 生成一个字符串,重复次数等于 count

app.use('/string', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'stringData|4': [{
      'repeat|1-3': '❤',
      'count|2': '😘'
    }]
  }))
})

image-20210707143138804

Number

  1. 'name|+1': number

    属性值自动加 1,初始值为 number

  2. 'name|min-max': number

    生成一个大于等于 min、小于等于 max 的整数,属性值 number 只是用来确定类型。

  3. 'name|min-max.dmin-dmax': number

    生成一个浮点数,整数部分大于等于 min、小于等于 max,小数部分保留 dmindmax 位。

app.use('/number', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'numberData|4': [{
      'selfIncreasing1|+1': 1,
      'selfIncreasing2|+2': 1, // 递增2
      'randomNumber1|1-100': 1, // 随机1-100
      'randomNumber2|50': 1, // 固定50
      'floatNumber1|1-100.1-4': 1, // 整数位1-100随机,小数位长度在1-4之间
      'floatNumber2|100.5': 1 // 整数位固定100,小数点后固定4位
    }]
  }))
})

image-20210707143154729

Boolean

  1. 'name|1': boolean

    随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/2。

  2. 'name|min-max': value

    随机生成一个布尔值,值为 value 的概率是 min / (min + max),值为 !value 的概率是 max / (min + max)

app.use('/boolean', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'booleanData|4': [{
      'boolean1|1': true,
      'boolean2|1-4': true
    }]
  }))
})

image-20210707143511061

Object

  1. 'name|count': object

    从属性值 object 中随机选取 count 个属性。

  2. 'name|min-max': object

    从属性值 object 中随机选取 minmax 个属性。

app.use('/object', (req, res) => {
  const obj = {
    name: 'king',
    age: 12,
    sex: '男',
    No: 6666166
  }
  res.json(Mock.mock({
    'dataStatus': 200,
    'objectData|4': [{
      'object1|1': obj,
      'object2|1-4': obj
    }]
  }))
})

image-20210707143836303

Array

  1. 'name|1': array

    从属性值 array 中随机选取 1 个元素,作为最终值。

  2. 'name|+1': array

    从属性值 array 中顺序选取 1 个元素,作为最终值。

  3. 'name|min-max': array

    通过重复属性值 array 生成一个新数组,重复次数大于等于 min,小于等于 max

  4. 'name|count': array

    通过重复属性值 array 生成一个新数组,重复次数为 count

app.use('/array', (req, res) => {
  const arr = [1, 2, 3, 4]
  res.json(Mock.mock({
    'dataStatus': 200,
    'arrayData|4': [{
      'order1|1': arr,
      'order2|+1': arr,
      'interval1|1-4': arr,
      'count1|2': arr,
    }]
  }))
})

image-20210707152105146

RegExp

  1. ‘name’: regexp

    根据正则表达式 regexp 反向生成可以匹配它的字符串。用于生成自定义格式的字符串。

app.use('/regexp', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'regexp|6': [{
      'phone': /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
      'caoNo': /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z](?:((\d{5}[A-HJK])|([A-HJK][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳])$/
    }]
  }))
})

image-20210707152609340

占位符

  1. @ 来标识其后的字符串是 占位符
  2. 占位符 引用的是 Mock.Random 中的方法。
  3. 通过 Mock.Random.extend() 来扩展自定义占位符
app.use('/placeholder', (req, res) => {
  res.json(Mock.mock({
    'dataStatus': 200,
    'placeholderData|4': [{
      id: '@guid',
      name: '@cname',
      color: '@color',
      title: '@ctitle',
      content: '@cparagraph'
    }]
  }))
})

image-20210707153443335

更多的占位符内容如下

Type Method
Basic boolean, natural, integer, float, character, string, range, date, time, datetime, now
Image image, dataImage
Color color
Text paragraph, sentence, word, title, cparagraph, csentence, cword, ctitle
Name first, last, name, cfirst, clast, cname
Web url, domain, email, ip, tld
Address area, region
Helper capitalize, upper, lower, pick, shuffle
Miscellaneous guid, id

到此为止Mock相关的大部分知识点已经列出来了,更多用法或者api的请看官网示例


前端小白