這次帶給大家怎麼實作在vue-cli專案中使用Mockjs,在vue-cli專案中使用Mockjs的注意事項有哪些,以下就是實戰案例,一起來看一下。
背景
前端在早期jQuery時代時,前端功能和後端工程基本上都是合在一起,典型的就是常見的maven工程下面的webapp目錄包含前端各類別靜態資源檔。
這個時候,我們總是會遇到這些問題:
老大,介面文件還沒輸出,我的好多活幹不下去啊!
後端小哥,介面寫好了沒,我要測試啊!
測試時間不夠啊,就要發版了,今天難道我有看明天的太陽升起?
諸如種種,就是一句話:勞資,再也不要指望你們了!
node出現之後,準確的說是前後端分離之後,前端迫切需要一種機制,不在需要依賴後端介面開發。經過這幾年的發展,有好多大牛在這方面進行了研究。
現在我們終於可以實現真實模擬測試啦。如今天的主角mockjs
使用詳解
1.首先在src 目錄建立mock 資料夾,定義mock 主檔案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);
2.在指定的檔案中定義模板函數類,範例:
// 获取 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, };
3.在main.js 中引入mock/index.js檔案;
// 引入mock文件 import './mock/index'; // mock 方式,正式发布时,注释掉该处即可
接下來的工作就是設定你的mock 路由以及模板函數啦。 Have Fun!
踩下的坑
#這裡我介紹在vue-cli 中使用Mockjs 踩到的坑:
1.請求路徑包含變量,我該怎麼辦?
使用過router 碼友知道,我們經常要處理位址中包含參數的路由,此時我們只需要在Mockjs 中使用正規表示式去匹配路徑即可完成,範例:
複製程式碼 程式碼如下:
Mock.mock(/\/api\/healthPlat\/getRecipeDetail\/\w*\/\w */, 'get', record.getRecipeDetail);
即我們只在變數的地方使用正規字元集合去匹配我們的變數。
2.為什麼在控制台裡面的 network 中沒有看到我的請求?
剛開始測試時,我查看 network 沒有看到請求,我感到很奇怪!就自問自己幾個問題:
為什麼在 main.js 入口檔案中引入 mockjs 的相關設定檔?
入口檔不都是在 webpack 中被編譯,然後在瀏覽器中執行的嗎?
控制台沒有攔截到請求,那就是沒有攔截到發送到伺服器的請求了,對吧?
帶著這些問題,閱讀源碼和文檔,發現:
#源碼中首先查找是否在Mockjs 中定義了該請求,有則進行攔截,然後使用其模擬請求物件MockXMLHttpRequest 進行回應,即此時不發送XHR 請求;
否則使用本地標準XHR 物件進行請求,此時可以在控制台network中看到請求訊息
因此,在main.js 入口檔案中引入mockjs 的相關設定文件,即是在前端程式碼中加入了Mockjs 的模擬方式,它將在瀏覽器中被執行,而不是真正的發送請求,不過我們可以將其列印到控制台進行查看。
網友評論可以在伺服器中使用mockjs ,此時就是真是的請求,可以在控制台中查看到請求信息,此處本人未進行相應實踐,有興趣的可以參看mock-server:
3.使用模板語法,傳回的資料裡麵包含規則“|rules”,導致解析或取值失敗,我該怎麼辦?
刚开始的时候,我按照文档上说的模板语法进行配置,如:
看到属性 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,基本符合我们测试要求,哈哈,机智不^<^。
4.模拟异步请求的过程,发现请求好像是瞬间完成,loading效果没生效
刚开始的时候,没有设置延迟响应,每次请求都好像是瞬间完成的,没有一步操作的那种等待感,没有看到loading罩层出现。
自己debug时,loading罩层是有的,于是想到:请求没有被延迟,而是被同步执行了。
想到lodash.debounce 函数有延迟网络请求、稀释事件、延迟执行的效果,于是将模板函数用 debounce 包裹起来,如下:
复制代码 代码如下:
Mock.mock('/api/healthPlat/chronicdisease', 'get', debounce(record.chronicdisease, 600));
结果出现有意思的事情:当请求比较频繁,在延迟时间内,本次请求得到的响应数据是上次请求的结果。这显然不是我们希望看到的,而且我们一般是用 debounce 的来稀释请求的,用在请求发送之后显然违背了我们的初衷。
翻阅 mockjs 文档,发现作者已经考虑了这个事情。哎,辛苦忙活了大半天,还是要好好看文档啊。具体如下:
Mock.setup({ timeout: 800, // 设置延迟响应,模拟向后端请求数据 });
5. Mock 无法拦截带参数的 get 请求
刚开始时,发现设置的有些 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 中,其他框架中亦可按此法进行配置。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
#以上是怎樣實作在vue-cli專案中使用Mockjs的詳細內容。更多資訊請關注PHP中文網其他相關文章!