本地 Mock 数据

本地 mock 数据主要依赖于webpack-dev-server的能力。

第一步:与src同级新建一个mock目录,目录里创建index.js文件,内容如下。

// src/mock/index.js
const path = require('path');
const fs = require('fs');

// 设置 mock api 的根目录
const rootDir = path.resolve(__dirname, 'rest');

// 获取所有需要 mock 的 api 列表,比如 ['/rest/a', '/rest/path/b']
const getApiList = (dir) => {
  let apiPaths = [];
  fs.readdirSync(dir, { withFileTypes: true }).forEach(function (dirent) {
    const filePath = path.join(dir, dirent.name);
    if (dirent.isFile()) {
      if (filePath.endsWith('.js')) {
        const api = filePath.replace(__dirname, '').replace('.js', '');
        apiPaths.push(api);
      }
    } else if (dirent.isDirectory()) {
      const subApiPaths = getApiList(filePath);
      apiPaths = apiPaths.concat(subApiPaths);
    }
  });
  return apiPaths;
};

const apiList = getApiList(rootDir);

module.exports = (app) => {
  apiList.forEach((api) => {
    ['get', 'post'].forEach((method) => {
      app[method](api, (req, res) => {
        const fileName = path.resolve(__dirname, api.slice(1) + '.js');
        const fileContent = fs.readFileSync(fileName, 'utf-8');
        let fnStr = fileContent.replace(/\s*module.exports\s*=\s*/, ''); // 函数的字符串格式

        // 删去函数闭合标签之后的内容,否则会报错
        let lastRightBraceIndex = fnStr.lastIndexOf('}');
        fnStr = fnStr.substring(0, lastRightBraceIndex + 1);

        // 将字符串函数转换成函数
        const fn = eval(`(false || (${fnStr}))`);

        // 返回函数执行结果
        res.json(fn(req, res));
      });
    });
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

第二步,在mock目录下新建rest目录(这个目录可以随便换,但是上一步代码里的rootDir也要跟着换)。每个接口都要新建一个js文件来放置想要 Mock 返回的数据。比如

// rest/a.js
module.exports = (req, res) => {
    // 这里可以根据 params 动态返回数据
    const { url, method, params } = req;
    return {
        code: 0,
        data: {
        a: 1,
        },
    };
};
1
2
3
4
5
6
7
8
9
10
11
// rest/path/b.js
module.exports = function (req) {
  const { url, method, params } = req;
  return {
    code: 1,
    errorMsg: '出错啦'
  };
};
1
2
3
4
5
6
7
8

第三步:在 Webpack 的devServer里配置before钩子,当启动项目且存在环境变量MOCKtrue时,就是启用 Mock 数据。

// vue.config.js
module.exports = {
    // ...
    devServer: {
        // ...
        before: process.env.MOCK === 'true' && require('./mock')
    }
}
1
2
3
4
5
6
7
8

第四步:添加脚本,以后本地开发项目想 mock 数据时,执行yarn run mock

// package.json
{
    "scripts": {
        "mock": "MOCK=true vue-cli-service serve"
    }
}
1
2
3
4
5
6