网上教程很多,但大多都是官网的照搬和堆砌,作者认为对于使用者来说,往往看了教程后,所学却不足以解决实际中的各种问题。所以本文介绍Mockjs的一些实践的用法,希望能帮助读者解决实际问题。
安装和入门
请认真阅读官方教程。
设置
常规情况下设置Mock接口的超时时间范围,模拟动态的网络环境。
Mock.setup({
timeout: '100-900',
});
Get查询参数匹配
在使用Get时,实际情况往往是有参数的。Mock的url参数如果直接指定字符串则时直接匹配,带了查询参数的URI则会被认为不匹配。所以Mock支持第一个参数传入一个RegExp对象进行正则匹配,对于常规情况只需要在URL后加上.*
即可。
Mock.mock(RegExp("/helloword.*"), 'get', req => {
return req.url;
});
两大概念
数据模板
数据模板是一个object对象,其中可以定义数据的模板结构,每个属性由:属性名、属性生成规则、属性值组成。
属性值可以为具体值作为默认值,也可为候选列表作为生成规则的数据来源,也可以为带数据占位符的字符串。
Mock.mock("/helloworld", 'post', {
"id|+1": 1,
"name": "Jack",
"teacher|1": ["Jone", "Sam", "Sherry"],
"brithday": "@date",
"age|20-35": 20,
});
数据占位符
数据占位符@
在属性的值中使用,用于访问模板中其他属性的生成值,或调用生成函数。
Mock.mock("/helloworld", 'post', {
"message": "hell0 @name",
});
参数模板
Mock的随机函数使用
Mock提供的随机函数很多,常用的比如:cname、datetime、email、guid等等。
Mock.mock("/userinfo", 'get', {
"createTime": "@datetime",
"name": "@cname", // 随机中文名
"email": "@email",
});
自定义的随机函数使用
举个简单的例子如下:
const address = ["张家界", "九寨沟", "泰山", "蓬莱"];
Mock.Random.extend({
// 自定义随机函数 Address
Address: function () {
return this.pick(address)
}
})
Mock.mock("/helloworld", 'post', {
"addr": "@Address", // 使用占位符访问随机函数
"addr|1": address, // 与前一行同样的效果,更加简单
});
简单的随机需求使用属性生成规则完全就可以搞定,没必要些自定义随机函数这么麻烦。
那么自定义随机函数一般不是用来解决简单的随机需求,而是利用函数的动态优势接收参数进行筛选。
const address = {
"todolist1": ["张家界", "九寨沟", "泰山", "蓬莱"],
"todolist2": ["成都", "重庆", "西安", "大理"],
"todolist3": ["理塘", "汶川", "新都桥", "稻城"],
};
Mock.Random.extend({
Address: function (listname) {
return this.pick(address[listname])
}
})
Mock.mock("/helloworld", 'post', {
"addr": "@Address('todolist3')",
});
对模板内其他属性的访问————占位符
对属性内其他属性的访问方式与随机函数的访问方式相同,Mock会优先尝试访问属性,其次才是随机函数。
Mock.mock("/helloworld", 'post', {
"expectedDays|10-30": 11, // 预期耗时天数
"actualDays": "@expectedDays", // 实际耗时天数,与预期的随机值一致
});
属性的访问方式分为相对路径与绝对路径,不是绝对路径的情况下,默认从属性当前层级开始查找。
Mock.mock("/helloworld", 'post', {
"a": 1,
"b": "@a",
"c":{
"c1": 2,
"c2": "@c1", // 相对路径访问,从当前层级寻找c1
"c3": "@../b", // 相对路径访问,从在层级中寻找属性b
"c3": "@/a", // 绝对路径访问,从模板顶层中寻找a
}
});
对模板内其他属性的访问——函数
Mock.mock("/helloworld", 'post', {
"a": 1,
"b": "@a",
"c":{
"c1": 2,
"c2": function (){
this.c.c1; // 函数使用this寻找当前模板生成的属性值
},
}
});
数组随机
Mock.mock("/helloworld", 'post', {
"arrayA|10": ["@integer(10, 200)"], // 生成一个长度为10的数组,每项值为10到200之间的随机数
});
关联的随机值
往往很多情况下我们需要构建的数据虽然随机,但是却希望其中产生的一些数据具备关联性,这种情况我们可以通过随机函数或函数属性来实现。
const CLASSES = {
"2023016001": "2023级电工1班",
"2023016002": "2023级电工2班",
"2023016003": "2023级电工3班!",
"2023014001": "2023级机械1班",
"2023014002": "2023级机械2班",
"2023014003": "2023级机械3班",
};
Mock.Random.extend({
ClassName: function (classCode) {
return CLASSES[classCode];
}
})
Mock.mock("/helloworld", 'post', {
"age|18-35": 22,
"brithday": function(){
const dateNow = new Date(Date.now);
return dateNow.setFullYear(-this.age);
},
"class|1": CLASSES,
"className": "@ClassName(@class)",
});
动态模板
很多场景下我们需要动态的生成一些数据,比如我们常需要动态生成数组长度的场景:
Mock.Random.extend({
Students: function (classSize) {
const template = {};
template[`array|${count}`] = [{
"id|+1": 1,
"name": "@name",
"age|16-18": 17,
}];
const data = Mock.mock(template);
return data.array;
}
})
Mock.mock("/helloworld", 'post', {
"classSize|40-60": 43,
"studentInfos": "@Students(@classSize)",
});
由示例可见通过占位符@访问随机函数得到想要的数据,也可以使用函数属性动态构建属性内容。
甚至,我们可以将全部模板在函数中构建和返回,这样就可以获取到options中上传的参数,根据不同的参数动态构建模板并生成返回数据。
Mock.mock("/helloworld", 'post', options => {
console.log(options);
const template = {
"name": "@name",
}
return Mock.mock(template);
});