前言
作为前端开发者,在前后端分离的时代下,不能一天到晚追着后端的同学要接口调试,我们可以自己来 Mock 现在的打包工具或者框架基本都支持或者通过第三方插件支持了 Mock 数据的能力。对于写死的静态数据而言,我们可以使用 MockJS 来生成动态的数据,这至少这样看起来更逼真,而且更方便,可以通过 Mock 的表达式来生成指定格式及数量的 JSON 数据。
进入官网,映入眼帘的是这么几个大字,简洁明了、突出主题
通过随机数据,模拟各种场景;不需要修改既有代码,就可以拦截 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>
在浏览器打开控制台就可以看见模拟的数据了
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数据已经不再是一个简单的数据,而是被包装成了一个比较像请求响应的对象
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页面,这时候会显示跨域错误
解决办法也很简单,在服务端设置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();
});
完成
语法规则
mock中的数据模板由三部分构成:属性名、生成规则和属性值
// 属性名 name
// 生成规则 rule
// 属性值 value
'name|rule': value
生成规则有7种格式,对应的含义需要根据属性值类型来确定
'name|min-max': value
'name|count': value
'name|min-max.dmin-dmax': value
'name|min-max.dcount': value
'name|count.dmin-dmax': value
'name|count.dcount': value
'name|+step': value
string
使用之前的node服务端程序运行
'name|min-max': string
通过重复
string
生成一个字符串,重复次数大于等于min
,小于等于max
。'name|count': string
通过重复
string
生成一个字符串,重复次数等于count
。
app.use('/string', (req, res) => {
res.json(Mock.mock({
'dataStatus': 200,
'stringData|4': [{
'repeat|1-3': '❤',
'count|2': '😘'
}]
}))
})
Number
'name|+1': number
属性值自动加 1,初始值为
number
。'name|min-max': number
生成一个大于等于
min
、小于等于max
的整数,属性值number
只是用来确定类型。'name|min-max.dmin-dmax': number
生成一个浮点数,整数部分大于等于
min
、小于等于max
,小数部分保留dmin
到dmax
位。
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位
}]
}))
})
Boolean
'name|1': boolean
随机生成一个布尔值,值为 true 的概率是 1/2,值为 false 的概率同样是 1/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
}]
}))
})
Object
'name|count': object
从属性值
object
中随机选取count
个属性。'name|min-max': object
从属性值
object
中随机选取min
到max
个属性。
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
}]
}))
})
Array
'name|1': array
从属性值
array
中随机选取 1 个元素,作为最终值。'name|+1': array
从属性值
array
中顺序选取 1 个元素,作为最终值。'name|min-max': array
通过重复属性值
array
生成一个新数组,重复次数大于等于min
,小于等于max
。'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,
}]
}))
})
RegExp
‘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挂学警港澳])$/
}]
}))
})
占位符
- 用
@
来标识其后的字符串是 占位符。 - 占位符 引用的是
Mock.Random
中的方法。 - 通过
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'
}]
}))
})
更多的占位符内容如下
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的请看官网示例