mock 数据 解决方案

前端工程化之--Mock解决方案   https://www.jianshu.com/p/720b12b5d120

一、为什么要使用mock数据:

  1、后端接口数据没有的时候,前端根据接口文档,使用 mock 数据模拟后端数据。(个人觉得 这里使用 mock数据并不是很重要,还要自己根据文档配数据)

  2、后端接口开发好,但是 测试环境数据有限,生产环境数据比较全。通过代理本地是可以直接使用生产环境的数据。但是如果生产环境代码有认证系统,认证通过,由服务器决定跳转到指定的 生产上的域名地址。页面没有跳转到本地的域名的地址,无法调试开发。

    但是测试环境是可以正常跳到 本地 域名页面的,这个时候可以把测试环境数据不足的接口使用MOCK数据(直接把生产上返回的数据直接复制到mock数据上就可以了,根本不需要直接配mock了)。【开发医保大数据就碰到这个情况】

  总结:mock 数据不要所有的接口都是mock数据。配了mock数据的接口,请求会被拦截,使用mock数据;没有配置的话,请求正常发出,从后端接口获取数据。【antd pro 脚手架安装的项目,就是这个逻辑的mock】


二、mockjs的使用说明

1、官网: http://mockjs.com/  或  https://www.cnblogs.com/CyLee/p/6072399.html (这个是使用 script 引入mockjs使用的)

2、Mock.mock() :   https://github.com/nuysoft/Mock/wiki/Mock.mock()

  a、Mock.mock( rurl, template )     ,当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。

  b、Mock.mock( rurl, function( options ) )    ,当拦截到匹配 rurl 的 Ajax 请求时,函数 function(options) 将被执行,并把执行结果作为响应数据返回。

3 、Mock.setup() : https://github.com/nuysoft/Mock/wiki/Mock.setup()

4、 Mock.Random :  https://github.com/nuysoft/Mock/wiki/Mock.Random   (Mock.Random 是一个工具类,用于生成各种随机数据。)

  这里面的随机数据基本包含可能会用到的所有数据。

5、扩展:  通过扩展,可以从自定义的数据中随机选取。(注意,新版的mockjs,对外暴露的接口只有Mock,所以Random方法挂在Mock对象下,即Mock.Random)

Random.extend({
    constellation: function(date) {
        var constellations = ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座']
        return this.pick(constellations)
    }
})
Random.constellation()
// => "水瓶座"

总结:直接使用mockjs作为假数据,在某些地方还是很好用的。比如返回多种不一样的随机数(需要过一会就变化的动态数据)。使用mockjs自带的接口可以很方便。

三、mockjs结合vue的使用【可以看mockjs的视频】

  mockjs 在项目中有两种用法:一种浏览器运行时生成mock数据;一种是服务器生成mock数据

  • 使用方法一:浏览器运行时生成mock数据
    mock数据在项目中的实践: renren-fast-vue 中mock 的处理是比较好的,推荐参考这个。
    需求:
      1、可控,通过传入参数 true/false 控制某个接口的 是否启用mock数据。
           2、非生产环境 不会引人 mock,使用require ,动态加载js 文件。
    import Mock from "mockjs";
    import * as common from "./modules/common";
    
    // tips
    // 1. 开启/关闭[业务模块]拦截, 通过调用fnCreate方法[isOpen参数]设置.
    // 2. 开启/关闭[业务模块中某个请求]拦截, 通过函数返回对象中的[isOpen属性]设置.
    fnCreate(common, false);
    
    /**
     * 创建mock模拟数据
     * @param {*} mod 模块
     * @param {*} isOpen 是否开启?
     */
    function fnCreate(mod, isOpen = true) {
      if (isOpen) {
        for (var key in mod) {
          (res => {
            if (res.isOpen !== false) {
              Mock.mock(new RegExp(res.url), res.type, opts => {
                opts["data"] = opts.body ? JSON.parse(opts.body) : null;
                delete opts.body;
                console.log("\n");
                console.log("%cmock拦截, 请求: ", "color:blue", opts);
                console.log("%cmock拦截, 响应: ", "color:blue", res.data);
                return res.data;
              });
            }
          })(mod[key]() || {});
        }
      }
    }
    // common.js
    import Mock from 'mockjs'
    
    // 登录
    export function login () {
      return {
        // isOpen: false,   // 这个决定某个接口是否需要mock
        url: '/sys/login',
        type: 'post',
        data: {
          'msg': 'success',
          'code': 0,
          'expire': Mock.Random.natural(60 * 60 * 1, 60 * 60 * 12),
          'token': Mock.Random.string('abcdefghijklmnopqrstuvwxyz0123456789', 32)
        }
      }
    }
    
    // 退出
    export function logout () {
      return {
        // isOpen: false,
        url: '/sys/logout',
        type: 'post',
        data: {
          'msg': 'success',
          'code': 0
        }
      }
    }
  • 使用方法二:服务器生成mock数据【推荐这种:webpack里面自带express,让express执行Mock的JS文件就可以了

    • nodejs运行下面的代码就可以产生mock数据。
      const Mock = require('mockjs')
      const id = Mock.mock('@id')
      console.log(id);
    • vue-cli中让代理的接口,返回我们自定的数据回去就可以了。webpack的devServer自带这个功能。
      注意:因为webpack版本的问题,新版webpack中 devServer 已经没有 before 属性了,而是使用 onBeforeSetupMiddleware 属性
      before(app){
        app.get('/some/path', function(req, res) {
          res.json({ custom: 'response' }); // 代理时匹配到这个url时,不发送真实的请求,把自己自己产生的数据给前端。
        });
      }

      新版webpack,使用 onBeforeSetupMiddleware属性,用法差不多。

          onBeforeSetupMiddleware: function (devServer) {
            if (!devServer) {
              throw new Error('webpack-dev-server is not defined');
            }
      
            devServer.app.get('/some/path', function (req, res) {
              res.json({ custom: 'response' });
            });
          },
    • 结合vue使用,我们只需要把 onBeforeSetupMiddleware 属性值,变成 我们 mock/index.js 导出的函数就可以了。
      // vue.config.js  中 把 onBeforeSetupMiddleware 属性值,设置mock/index导出的函数
      const { defineConfig } = require('@vue/cli-service')
      const mock = require('./mock/index')
      
      module.exports = defineConfig({
        transpileDependencies: true,
        devServer: {
          onBeforeSetupMiddleware: mock
        }
      })
      // mock/index.js
      const Mock = require('mockjs')
      const fs = require('fs')
      const path = require('path')
      const json5 = require('json5')
      const { mock } = require('mockjs')
      
      function getJsonFile(filePath){
          const jsonString = fs.readFileSync(path.join(__dirname, filePath))
          return json5.parse(jsonString)
      }
      
      
      module.exports = function(devServer){
          devServer.app.get('/some/path', function (req, res) {
              var json = getJsonFile('./userInfo.json5')
              res.json(Mock.mock(json))
          })
      }
      // userInfo.json5 文件, 这个文件就是放数据的
      
      {
          name: '@id', // 姓名
          age: "@integer(10, 30)"
      }
      说明:1、onBeforeSetupMiddleware 和 proxy是共存的。onBeforeSetupMiddleware 里面是自己手动给express 配置路由。有接口发送请求,先到expess路由找,
                       如果没找到匹配的就会走proxy配置的地址向外发送请求。(这个是自己测试得出的结论)
                 2、readFileSync 读取文件,每次都是从硬盘读取的,不会从缓存读取。所以直接修改mock数据文件,也会生效的。

    • 当后台数据写好了,怎么移除mock:【关键  要用到环境变量】

 

 

 

总结: mock.js        的优势在于可以通过   js 程序生成 任意数量且随机的数据(如果数据条数很多,js用一个循环就可以生成,这样就提现出优势来了); 

           mock服务器  的数据需要自己对应一个一个输入,使用这种方式完全不需要去配置,很方便,而且是完全接近真实运行环境的。(推荐这种方式,开发时很少会用到大量的数据,自己设置字段也不会很复杂)

 

posted @ 2018-09-04 13:25  吴飞ff  阅读(983)  评论(0编辑  收藏  举报