Mockjs 实践用法

314 阅读4分钟

网上教程很多,但大多都是官网的照搬和堆砌,作者认为对于使用者来说,往往看了教程后,所学却不足以解决实际中的各种问题。所以本文介绍Mockjs的一些实践的用法,希望能帮助读者解决实际问题。

安装和入门

请认真阅读官方教程

💡 Tips: 官方教程连贯度不是很友好,可结合参考 博客1 博客2 博客3,差异处以官方教程为准

设置

常规情况下设置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的数组,每项值为10200之间的随机数
});

关联的随机值

往往很多情况下我们需要构建的数据虽然随机,但是却希望其中产生的一些数据具备关联性,这种情况我们可以通过随机函数或函数属性来实现。

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);
});