前端在早期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 中,其餘框架中亦可按此法進行配置。上述有不盡之處或是紕漏之處,還望指正,鳴謝!