前端在早期jQuery时代时,前端功能和后端工程基本上都是合在一块儿,典型的就是常见的maven工程下面的webapp目录包含前端各种静态资源文件。
这个时候,咱们老是会遇到这些问题:前端
诸如种种,就是一句话:劳资,不再要期望大家了!
node出现以后,准确的说是先后端分离以后,前端迫切须要一种机制,不在须要依赖后端接口开发。通过这几年的发展,有好多大牛在这方面进行了研究。
如今咱们终于能够实现真实模拟测试啦。现在天的主角 mockjsvue
index.js
,在该文件中定义拦截路由配置;/** * 定义本地测试接口,最好与正式接口一致,避免联调阶段修改工做量 */ // 引入mockjs import Mock from 'mockjs'; // 引入模板函数类 import record from './presc-record-api'; Mock.setup({ timeout: 800, // 设置延迟响应,模拟向后端请求数据 }); // Mock.mock( url, post/get , 返回的数据); Mock.mock(/\/api\/healthPlat\/getRecipe\/\w*\/\w*/, 'get', record.getRecipe);
// 获取 mock.Random 对象 // 引入mockjs import { Random } from 'mockjs'; import Utils from './Utils'; function getRecipe(req) { // mock一组数据 const data = []; for (let i = 0; i < 10; i += 1) { const o = { recipeId: Random.guid(), billId: Random.string(10), orgId: Random.string('number', 8, 10), viewName: Random.cword(4, 16), // 随机生成任意名称 personName: Random.cname(), reason: Random.csentence(10, 32), }; data.push(o); } // 返回响应数据对象 return Utils.setRes(req, { data: { idCard: Random.id(), // 随机 details: data, }, totalCount: 20, }); } export default { getRecipe, };
main.js
中引入 mock/index.js
文件;// 引入mock文件 import './mock/index'; // mock 方式,正式发布时,注释掉该处便可
接下来的工做就是配置你的 mock 路由以及模板函数啦。Have Fun!node
这里我介绍一下在 vue-cli 中使用 Mockjs 踩到的坑:webpack
使用过 router 码友知道,咱们常常要处理地址中包含参数的路由,此时咱们只须要在 Mockjs 中使用正则表达式去匹配路径便可完成,示例:git
Mock.mock(/\/api\/healthPlat\/getRecipeDetail\/\w*\/\w*/, 'get', record.getRecipeDetail);
即咱们只在变量的地方使用正则字符集合去匹配咱们的变量。github
刚开始测试时,我查看 network 没有看到请求,感到很奇怪!就自问本身几个问题:web
main.js
入口文件中引入 mockjs
的相关配置文件?带着这些问题,阅读源码和文档,发现:正则表达式
所以,在 main.js
入口文件中引入 mockjs
的相关配置文件,便是在前端代码中加入了 Mockjs 的模拟方式,它将在浏览器中被执行,而不是真正的发送请求,不过咱们能够将其打印到控制台进行查看。
网友评论能够在服务器中使用 mockjs ,此时就是真是的请求,能够在控制台中查看到请求信息,此处本人未进行相应实践,有兴趣的能够参看 mock-server: vue-cli
刚开始的时候,我按照文档上说的模板语法进行配置,如:npm
看到属性 code
竟然带着规则一块儿返回了,我说我请求为啥没有解析成功啊,原来 res.code
一直是 undefined
,这是坑啊。
查看源码和能够搜到的网上示例发现:没有使用模板规则的现象,而是使用 mockjs
提供的内置函数来实现,如 .id()
.cname()
等等方法。
因而我将mock相关文件中 code 定义改为下面这样:
function setRes(req, options) { window.console.log(req.url); const { code = Random.int(0, 5) >= 1 ? 1 : 0, message, data = {}, totalCount = 100 } = options; const result = { code, message: message || ['失败', '错误', '异常'][Random.integer(0, 2)], data, totalCount, }; window.console.log(result); return result; }
刚开始的时候属性code
是这样定义的—— 'code|1', true,
,后来改为了 code = Random.boolean(),
,发现生成 false 的概览过高了,不适合咱们真实的场景。
想到咱们只须要增长 code
为 1 的几率,因而本人使用 Random.int(0, 5)
随机生成一个整数,当这个整数大于等于1,咱们将 code
设置为 1 ,其余状况为 0 。
也就是说从几率上将,成功的几率为 0.8,失败的几率为 0.2,基本符合咱们测试要求,哈哈,机智不^<^。
刚开始的时候,没有设置延迟响应,每次请求都好像是瞬间完成的,没有一步操做的那种等待感,没有看到loading罩层出现。
本身debug时,loading罩层是有的,因而想到:请求没有被延迟,而是被同步执行了。
想到 lodash.debounce 函数有延迟网络请求、稀释事件、延迟执行的效果,因而将模板函数用 debounce 包裹起来,以下:
Mock.mock('/api/healthPlat/chronicdisease', 'get', debounce(record.chronicdisease, 600));
结果出现有意思的事情:当请求比较频繁,在延迟时间内,本次请求获得的响应数据是上次请求的结果。这显然不是咱们但愿看到的,并且咱们通常是用 debounce 的来稀释请求的,用在请求发送以后显然违背了咱们的初衷。
翻阅 mockjs 文档,发现做者已经考虑了这个事情。哎,辛苦忙活了大半天,仍是要好好看文档啊。具体以下:
Mock.setup({ timeout: 800, // 设置延迟响应,模拟向后端请求数据 });
刚开始时,发现设置的有些 get
请求老是请求不到 mock 的数据,而有些 get
请求能获得 mock 的数据,post
则不存在这样的问题。很是郁闷!
仔细 debug 时发现:get
请求带参数时失败,找不到路径;get
请求不带参数成功,路径没找到,获取到 mock 的数据;post
路径正确找到,成功获得 mock 数据。
这时忽然意思到:get
请求的路径默认后面会加上参数,所以和设置的路径没有匹配上,致使路径没找到,请求失败。
因而本人将路径改为正则表达式,就行了。如:
// 刚开始字符串路径,带参数的 get 请求匹配失败 Mock.mock('/api/healthPlat/renewCancel', 'get', manage.renewCancel);
改为下面这样就行了:
// 正则表达式路径,带参数的 get 请求匹配成功 Mock.mock(/\/api\/healthPlat\/renewCancel/, 'get', manage.renewCancel);
可是实际开发过程当中,发现上述正则表达式不够完备,如后续咱们又另外一个路径 /api/healthPlat/renewCancelAddr
也会匹配上述地址,这不是咱们但愿有的。
此时咱们只需改进下正则表达式便可:
// 正则表达式路径,带参数的 get 请求匹配成功 Mock.mock(/\/api\/healthPlat\/renewCancel(|\?\S*)$/, 'get', manage.renewCancel);
即只有路径为 /api/healthPlat/renewCancel
的 get
请求才会匹配上述规则。
最后建议:get
请求都用正则表达式书写路径;post
字符串和正则都行;
mock虽然存在以上所涉及的局限和问题,不过对于平常自测联调仍是颇有益处,我的以为主要仍是简单可行。固然本文所述方式,不只仅局限在 vue-cli 中,其余框架中亦可按此法进行配置。上述有不尽之处或是纰漏之处,还望指正,鸣谢!