mock.js-無需等待,讓前端獨立于后端進行開發
概述
- 首先啦,我不認識mock.js的作者,帶著需求找到mock.js讓我覺得很驚艷。
- 相對于其他同類的框架的實現,mock.js超出了我的意料。
- 基于 數據模板 生成模擬數據。
- 基于 HTML模板 生成模擬數據。
- 攔截并模擬 ajax 請求。 </ul> </li>
- 是的,mock.js只做上述的幾件事,但做的足夠出色。 </ul>
- 數據太長了,將數據寫在js文件里,完成后挨個改url。
- 某些邏輯復雜的代碼,加入或去除模擬數據時得小心翼翼。
- 想要盡可能還原真實的數據,要么編寫更多代碼,要么手動修改模擬數據。
- 特殊的格式,例如IP,隨機數,圖片,地址,需要去收集。
- 超爛的破網速…
- … </ul>
- 代碼示例:
~location.search.indexOf('mock') && require('mock/index');
- 背景:為了靈活控制是否啟用模擬數據我們會在url上新增mock參數,有mock就會加載數據模板,沒有就不會加載,但是上面代碼沒有達到這一目的,不管url上有無mock參數,都會加載數據模板
- 原因:因為seajs內部的預加載機制,只要代碼里進行了require某個文件,它都會解析文件依賴關系,從而下載這些文件;
-
解決辦法:
var module = ['page/index/index']; if (~location.search.indexOf('mock')) module.push('mock/index');
seajs.use("business/router", function (router) { router.ready(function (params, index) { index.init(params); }, module); });</pre>
這里,我們在html頁面入口部分,根據url是否含有mock來動態選擇需要異步加載的模塊,從而解決了這一問題。
</li> </ul>2.項目使用了net.js對ajax請求進行了一層封裝,無法攔截ajax請求。
- 代碼示例:
Mock.mock('a.json', { result: 0, errmsg: 'ok', data: { 'list|0-10': [{ 'icon': '@image', 'nick': '@name', 'inviteTime': '@date' }], 'hasMore|0-1': 1, 'invitePeopleNum|1-50': 20, 'getAwardNum|10-600': 12, 'hasAward|0-1': 1 } }); net.ajax({ url: 'a.json', data: { module: "invite_chest_box", method: "GetInviteList", param: { "tt": "2", "appId": "1000001034", "pageNo": 0, "pageCount": 10 } }, cache: false, dataType: 'json', success: function (json) { //成功之后回調 console.log(json) } });
- 背景:mock.js因為默認內置jQuery、Zepto、KISSY的攔截ajax請求,由于我們項目中對ajax請求專門做了一層封裝,所以無法攔截ajax請求。
-
解決方案:
var net = require('util/net'); Mock.mockjax(net);
調用mackjax方法,將攔截操作注入net.ajax中,從而攔截ajax才會生效。
</li> </ul>3.一個項目cgi名稱和模塊名相同,不同接口使用method來區分,通過method無法區分不同接口和攔截ajax請求。
-
代碼示例:
Mock.mock(/getInviteList/, { result: 0, errmsg: 'ok', data: { 'list|0-10': [{ 'icon': '@image', 'nick': '@name', 'inviteTime': '@date' }], 'hasMore|0-1': 1, 'invitePeopleNum|1-50': 20, 'getAwardNum|10-600': 12, 'hasAward|0-1': 1 } }); $.ajax({ url: 'http://gift.gamecenter.qq.com/cgi-bin/gc_invite_chest_box_fcgi', data: { module: "invite_chest_box", method: "GetInviteList", param: { "tt": "2", "appId": "1000001034", "pageNo": 0, "pageCount": 10 } }, cache: false, dataType: 'json', success: function (json) { //成功之后回調 console.log(json) } });
Mock.mock的第一個參數為匹配的規則,可以是字符串,也可以是正則,這里我們用cgi的method來匹配當前cgi,但是可惜的是沒有匹配到
</li> - 原因:
- 解決方案:
查看源碼我們發現,當匹配規則為字符串時,匹配規則必須要與請求url完全一致才行,當匹配規則為正則時,需要在請求url上檢查是否存在滿足的匹配,所以不管是字符串匹配還是正則匹配,都只是在url上查找匹配,并不能匹配data內部的參數(比如method:GetInviteList)
這里將options里面的data對象也都納入檢查匹配的范疇,都是將兩處的匹配檢查都改成了正則匹配,都是忽略字母大小寫,這樣,我們就可以根據data內部的任意參數來匹配不同的cgi請求,大大提高了匹配的靈活性。
查看響應的結果
{ "result": 0, "errmsg": "ok", "data": { "list": [ { "icon": "http://dummyimage.com/120x600", "nick": "Charles Hernandez", "inviteTime": "1988-09-26" }, { "icon": "http://dummyimage.com/120x60", "nick": "Linda Garcia", "inviteTime": "1991-09-14" } ], "hasMore": 0, "invitePeopleNum": 45, "getAwardNum": 511, "hasAward": 0 } }
原文 http://www.cnblogs.com/fengyuqing/p/mockjs.html -
- 代碼示例:
解決的問題
開發時,后端還沒完成數據輸出,前端只好寫靜態模擬數據。
使用過程中遇到的問題及相應解決方案
1.項目基于seajs開發,所以不能根據 URL 中是否含有參數 mock 動態加載數據模板。