模拟数据Mock.js实用指南

7,549 阅读5分钟

前言

在前后端分离的开发模式下,前端程序员和后端程序员之间往往事先商量好接口格式,然后各自同步进行开发。一般来说,前端开发的进度要快于后端,在后端接口还没有完成的情况下,前端就需要自己先模拟数据进行页面调试,这样等后端接口开发完成后,只要替换一下接口地址就可以直接上线。

今天我们就来学习一款模拟数据的工具Mock.js(官网),他的特点就三个:简单,简单,还是TMD简单。Mock.js的核心API就两个(Mock.mockMock.Random),不需要其他任何依赖,但足以满足需要。下面我通过三个使用场景来介绍一下Mock.js的使用。

通过模板生成数据

模拟数据最常用的就是通过模板,Mock.js通过Mock.mock实现模板的定义和解析,同时Mock.js定义了一套模板规则,我们只需要使用这些规则就可以模拟任意需要的数据。官方文档给出了两种规范,一个叫模板定义规范,一个叫占位符规范,我觉得不如分场景介绍来的直观,我们往下看。

生成对象类型数据

对象类型的数据是我们最常用的一类,Mock.js中的模板定义规范(DTD)也是针对对象类型数据的,基本格式如下:

{
  '属性名1|规则1': '值1',
  '属性名2|规则2': '值2',
  ...
}

属性名还是正常的固定字符串,这里面没有什么可以模拟的,核心是如何模拟值

值的模拟有两种方式,规则和占位符。 规则用于控制值的生成策略,比如数字的范围、随机选取、重复几次等,占位符可以理解为方法的调用,生成特定的数据,比如姓名、城市、邮箱、图片等。

规则如何生效取决于值的类型,注意模板中的值不是真正的值,Mock.js会结合规则对这些值做处理之后才会产生最终值。我们举个例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdn.bootcdn.net/ajax/libs/Mock.js/1.0.0/mock-min.js"></script>
    <title>Document</title>
  </head>
  <body>
    <script>
      console.log(
        Mock.mock({
          'number|1': [1, 2, 3, 4, 5],
          'array|2': [1, 2, 3, 4, 5],
        })
      );
    </script>
  </body>
</html>

image.png

我们可以发现同样传入了数组,但number最终是一个数字,array最终是将数组复制了2份,这就是规则对于值的处理。我们可以在官方文档查看到其它的规则,按需使用即可。

占位符的基本格式是'@名称',比如@name @city等。这个使用起来比较简单,我们举个例子:

  <body>
    <script>
      console.log(
        Mock.mock({
          name: '@name',
          city: '@city',
          email: '@email',
        })
      );
    </script>
  </body>

image.png

占位符本质是对方法的调用,所有的占位符名称都和Mock.Random对象的方法名一样,所以要想知道有哪些占位符可以使用,就到官方文档查看Random上有哪些方法即可。

既然占位符是对方法的调用,那么方法中可以传入的参数,占位符也可以传入,我们举个例子:

  <body>
    <script>
      console.log(
        Mock.mock({
          name: '@cname',
          age: '@ineger(0,100)',
        })
      );
    </script>
  </body>

image.png

当然规则和占位符可以混合使用,占位符本质还是个字符串,我们举个例子:

  <body>
    <script>
      console.log(
        Mock.mock({
          'name|2': '@name',
          'city|2': '@city',
          'email|2': '@email',
        })
      );
    </script>
  </body>

image.png

在这个例子中,我们通过规则将每个占位符都复制了2份,然后每个占位符再进行解析。

生成其它类型数据

对于其它类型的数据,比如字符串、数字、数组等,规则就不好使了,我们只能使用占位符,我们举个例子:

  <body>
    <script>
      console.log(Mock.mock('@name'));
      console.log(Mock.mock('@integer(10,20)'));
    </script>
  </body>

image.png

不通过模板生成数据

如果我们不想通过模板生成数据,而是希望在任意位置都能够生成模拟值,就可以通过调用Mock.Random对象的方法来实现,前面我们说模板中的占位符本质就是Random对象的方法调用,这里由于我们不使用模板,占位符就不能用了,只能直接调用Random对象的方法。官方文档中列出了Random对象的所有方法,我们举个例子:

  <body>
    <script>
      let Random = Mock.Random;
      console.log({
        name: Random.cname(),
        age: Random.integer(0, 100),
      });
    </script>
  </body>

image.png

模拟接口调用返回数据

对于前端来说,模拟数据最重要的是能够模拟接口调用,这样就可以像调用真实接口一样去进行页面调试,Mock.js当然也提供了这种功能,而且还是通过老朋友Mock.mockAPI来实现(官方文档),语法如下:Mock.mock(url,method,template|function(options))。我们依次解释一下:

  • url: 要拦截的URL,可以是字符串或者正则
  • method: 要拦截的请求方法,比如GET、POST等
  • template: 生成数据的模板
  • function(options): 执行函数并将返回值作为数据
    • options中包含ajax请求的参数,包括url,method,body

通过模板返回数据

首先我们看一下通过模板返回数据,这个是最常用的,举个例子:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdn.bootcdn.net/ajax/libs/Mock.js/1.0.0/mock-min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
    <title>Document</title>
  </head>
  <body>
    <button>click</button>
    <script>
      Mock.mock('/users', {
        code: 1000,
        'data|3-5': [
          {
            name: '@cname',
            age: '@integer(0,100)',
          },
        ],
      });
      document.querySelector('button').onclick = function () {
        axios.get('/users').then((data) => {
          console.log(data);
        });
      };
    </script>
  </body>
</html>

image.png

我们发现确实获取到了数据,再来看看Network有没有请求发出

image.png

我们发现并没有请求发出,这就证明Mock.js确实拦截了我们的请求并直接返回了数据。

通过函数返回数据

通过函数返回数据一般用的不多,因为返回值中不能使用模板,如果需要对请求参数做判断,则可以使用。我们看个例子:

<body>
    <button>click</button>
    <script>
      Mock.mock('/user/1', function (options) {
        if (options.type === 'POST') {
          return {
            code: 1000,
            result: '更新成功',
          };
        } else {
          return {
            code: 1000,
            data: {
              name: 'zhangsan',
              age: 20,
            },
          };
        }
      });
      document.querySelector('button').onclick = function () {
        axios.get('/user/1').then((data) => {
          console.log(data);
        });
        axios
          .post('/user/1', {
            name: 'lisi',
            age: 18,
          })
          .then((data) => {
            console.log(data);
          });
      };
    </script>
  </body>

image.png

不过个人不推荐这种用法,如果接口规范一点的话,完全可以通过Mock.mock('/user/1', 'GET', {xx})Mock.mock('/user/1', 'POST', {xx})来实现。

尾声

Mock.js是一款轻量的数据模拟库,很符合自己小而美的倾向,本文通过常见的几个场景把Mock.js的主要用法串了一遍,希望能对大家有所帮助。