Mock的方式
- 在client端處資料mock
- 在server端mock(json-server與faker.js)
- 第一種方式攔截了請求的發出,直接返回mock的資料,而第二種方式請求則真實地發出,只是在server端進行route攔截
- 前後端分離的方式,就是在傳統開發模式中加了一個node層,這樣資料mock完全可以在node server端完成
client mock
- 攔截所有請求
- 進行url規則匹配
- 匹配對的,返回mock資料
- 匹配不對的,走原本流程
mock.js
1.概念
mock.js是一個模擬資料生成器,幫助前後端分離。它可以根據資料模版生成模擬資料,模擬Ajax請求,生成隨機資料返回。
2.使用語法
Mock.js 的語法規範包括兩部分
- 資料模板定義規範
- 資料佔位符定義規範
詳細請看:mock.js文件連結
// 記錄資料模板。當攔截到匹配 rurl 的 Ajax 請求時,將根據資料模板 template 生成模擬資料,並作為響應資料返回。
Mock.mock( rurl, rtype, function( options ) )
rurl
可選。
表示需要攔截的 URL,可以是 URL 字串或 URL 正則。例如 /\/domain\/list\.json/、'/domian/list.json'。
rtype
可選。
表示需要攔截的 Ajax 請求型別。例如 GET、POST、PUT、DELETE 等。
template
可選。
表示資料模板,可以是物件或字串。例如 { 'data|1-10':[{}] }、'@EMAIL'。
function(options)
可選。
表示用於生成響應資料的函式。
options
指向本次請求的 Ajax 選項集,含有 url、type 和 body 三個屬性,參見 XMLHttpRequest 規範。
複製程式碼
示例
Mock.mock('/api/getName', { name: 'Jack', 'age|10-20': 10 });
複製程式碼
3. 模板語法
1)資料模板定義規範(例舉)
'name|min-max': string
Mock.mock({
"string|1-10": "★"
})
// result
{
"string": "★★★"
}
複製程式碼
'name|count': string
Mock.mock({
"string|3": "★★★"
})
// result
{
"string": "★★★★★★★★★"
}
複製程式碼
2)Mock.Random Mock.Random 是一個工具類,用於生成各種隨機資料。
Mock.Random 的方法在資料模板中稱為『佔位符』,書寫格式為 @佔位符(引數 [, 引數]) 。
var Random = Mock.Random
Random.email()
// => "n.clark@miller.io"
Mock.mock('@email')
// => "y.lee@lewis.org"
Mock.mock( { email: '@email' } )
// => { email: "v.lewis@hall.gov" }
複製程式碼
// Random.datetime()
Random.datetime()
Mock.mock('@datetime')
Mock.mock('@datetime()')
// Random.datetime( format )
Random.datetime('yyyy-MM-dd A HH:mm:ss')
Random.datetime('yy-MM-dd a HH:mm:ss')
Random.datetime('y-MM-dd HH:mm:ss')
Random.datetime('y-M-d H:m:s')
Mock.mock('@datetime("yyyy-MM-dd A HH:mm:ss")')
Mock.mock('@datetime("yy-MM-dd a HH:mm:ss")')
Mock.mock('@datetime("y-MM-dd HH:mm:ss")')
Mock.mock('@datetime("y-M-d H:m:s")')
Mock.mock('@datetime("yyyy yy y MM M dd d HH H hh h mm m ss s SS S A a T")')
//result
// Random.datetime()
"1984-03-11 21:34:12"
"2011-07-11 01:17:12"
"2007-03-25 16:31:51"
// Random.datetime( format )
"2018-01-27 AM 01:57:13"
"98-09-12 pm 21:34:08"
"71-06-03 07:13:40"
"15-1-20 11:58:41"
"1991-09-17 PM 15:41:03"
"99-09-11 am 01:00:15"
"71-03-21 10:16:52"
"14-12-10 16:32:53"
"1976 76 76 09 9 29 29 06 6 06 6 12 12 33 33 184 184 AM am 212796753184"
複製程式碼
4. 缺點
無法攔截fecth請求
fetch-mock
1. 概念
攔截fecth請求,進行mock資料返回
2. 模板語法
fetchMock.mock(matcher, response)
複製程式碼
常用:
fetchMock.once() //限制了只被呼叫一次
fetchMock.restore() //恢復其unstubbed fetch()狀態和清除所有資料記錄
複製程式碼
3. 用法
- 安裝
npm install mockjs
- 需要安裝fetch-mock包
--yarn add fetch-mock
,這個包主要用來包裝fetch- 註冊mock 攔截資訊的,應該是在App入口的位置
if(process.env.__DEV__) {
require('./mock/todolist')
}
複製程式碼
- 主要增加了mock資料夾,todolist.js是模擬資料
import FetchMock from 'fetch-mock';
FetchMock.mock('*', (url, options) => {
//解析獲取opt
if(opt==='9'){
return {
// mock資料
};
}
if(opt==='155'){
return {
// mock資料
};
}
else {
//恢復其unstubbed fetch()狀態和清除所有資料記錄
FetchMock.restore();
return fetch(url, options);
}
// FetchMock.restore();
// return fetch(url, options);
});
複製程式碼
3. 專案的業務規則
專案目前情況:同一個url請求,通過opt進行判斷呼叫哪個業務介面,因此無法直接使用url進行區分匹配,需要更詳細的判斷
實際請求程式碼
params.opt = opt
let dataString = ''
let index = 0
const keys = Object.keys(params)
keys.forEach((key) => {
if (index != 0) {
dataString += '&'
}
index++
const data = params[key]
const encodeData = encodeURIComponent(data)
dataString += `${key}=${encodeData}`
})
// opt最終會合併到dataString中,因此使用的時候,需要解析
let fetchPromise = fetch(url, {
method: 'post',
body: dataString,
headers: header,
}).then((response) => {
if (response.ok) {
return response.json()
} else {
throw new Error('網路錯誤')
}
})
複製程式碼
fetch-mock中
FetchMock.mock('*', (url, options) => {
var dataString = options.body;
var array = dataString.split("&")
var opt;
for (var temp of array) {
var temps = temp.split("=")
var key = temps[0]
var value = decodeURIComponent(temps[1])
if (key === "opt") {
opt = value;
}
}
if (opt === 195) {
// 進行轉發請求
} else {
FetchMock.restore();
// 走正常請求
}
})
複製程式碼
server mock
1. 簡單構建一套mock-server
為了更好的分工合作,讓前端能在不依賴後端環境的情況下進行開發,其中一種手段就是為前端開發者提供一個 web 容器,這個本地環境就是 mock-server
2. 一個比較好的 mock-server 該有的能力
- 與線上環境一致的介面地址,每次構建前端程式碼時不需要修改呼叫介面的程式碼
- 所改即所得,具有熱更新的能力,每次增加修改 mock 介面時不需要重啟 mock 服務,更不用重啟前端構建服務
- 能配合 Webpack
- mock 資料可以由工具生成不需要自己手動寫
- 能模擬 POST、GET 請求
3. 使用json-server模擬伺服器API
以 json-server 作為 mock 伺服器, mock.js 生成mock 資料,json-server支援各種GET/POST/PUT/DELETE的請求
簡單使用
1)安裝json-server
npm install -g json-server
2)發起fecth請求
import FetchMock from 'fetch-mock';
//其他路由使用原生fetch
FetchMock.mock('*', (url, options) => {
//opt解析
var array = options.body.split("&")
var opt;
for (var temp of array) {
var temps = temp.split("=")
var key = temps[0]
var value = temps[1]
if(key==='opt'){
opt = value
}
}
//opt匹配,發出fecth請求,進行mock資料返回
if(opt==='9'){
FetchMock.restore();
return fetch('http://localhost:53000/data');
}
if(opt==='155'){
FetchMock.restore();
return fetch('http://localhost:53000/list');
}
else {
FetchMock.restore();
return fetch(url, options);
}
// FetchMock.restore();
// return fetch(url, options);
});
複製程式碼
3)生成一個json.js檔案,結合mock.js動態生成模擬資料
var Mock = require('mockjs');
module.exports = () => {
// 使用 Mock
var datas = Mock.mock({
data:
{
//mock資料
}
,
list:{
//mock資料
"error": 0,
"message": "success",
'capitalDetails|30': [
{
//mock.js動態生成模擬資料
"summary": "@ctitle",
"time": "@datetime",
}
]
}
});
// 返回的data會作為json-server的資料
return datas;
};
複製程式碼
4)啟動json-server ,把一個js檔案返回的資料託管成web服務
json-server --watch --port 53000 json.js
成功時控制檯輸出:
shubing-mac:mock admin$ json-server --watch --port 53000 json.js
\{^_^}/ hi!
Loading json.js
Done
Resources
http://localhost:53000/data
http://localhost:53000/list
Home
http://localhost:53000
Type s + enter at any time to create a snapshot of the database
Watching...
複製程式碼
缺點
每次修改資料模版時,必須重新啟動mock伺服器
4.使用Faker.js
自動生成大量fake的json資料,作為後端資料