JS技巧多狀態(tài)頁面中的mock方案詳解
引言
我們有時候會遇到一個業(yè)務(wù)頁面存在很多個狀態(tài),甚至子狀態(tài),比如訂單詳情就是其中的典型,涉及從訂單創(chuàng)建到訂單結(jié)束,以及售后等流程。維護起來每個狀態(tài)對應一份數(shù)據(jù),雖然我們 QA 提供了數(shù)據(jù)構(gòu)造平臺,但構(gòu)造一份對應狀態(tài)的數(shù)據(jù)還是需要花費不少時間,而且串行流程一旦出錯的話只能重新來一遍。
后期維護階段也不容易構(gòu)造對應狀態(tài)的數(shù)據(jù),導致排查頁面問題比較耗時。
另外一個問題就是從頭熟悉業(yè)務(wù)的話成本比較高,如果有一個直觀的頁面能夠看到頁面樣式會好很多。
以上就是設(shè)計一個多狀態(tài) mock 工具初衷,讓開發(fā)者在頁面中直接選擇對應狀態(tài),就可以切換到對應頁面。
技術(shù)選型
目前轉(zhuǎn)轉(zhuǎn) app 測試包,webview 頁面氣泡浮層已經(jīng)有兩個了——客戶端工具和 eruda,再多就亂套了,所以最好集成在現(xiàn)有的工具基礎(chǔ)上??蛻舳瞬糠止δ芪覀兘佑|不到也不了解,在現(xiàn)有條件下只有 eruda 可用。
Eruda 是一個很強大的前端頁面調(diào)試工具庫,我們客戶端 webview 也內(nèi)置了,在測試包中可以很方便的借助 eruda 調(diào)試頁面,觀察日志。同時 eruda 也支持插件,通過插件來擴展 eruda 的功能。 我們的工具就基于 eruda 插件來實現(xiàn)。
實現(xiàn)效果預覽:

總體流程如下:

整個流程大概三個部分組成
- 業(yè)務(wù)邏輯改造
- Eruda 插件
- mock 數(shù)據(jù)整理
業(yè)務(wù)邏輯改造
首先要實現(xiàn)這樣一個方案核心依賴于業(yè)務(wù)使用的請求庫,以及是否能夠?qū)φ埱髱爝M行修改。
我們業(yè)務(wù)使用的基于 axios 的請求庫,其暴露了實際發(fā)送請求的 adapter 邏輯,我們可以基于 adapter 來實現(xiàn)接口方法的攔截。

axios adapter
借助 axios-mock-adapter[1],可以很方便的實現(xiàn)我們的需求。
import { axiosInstance } from '@zz/fetch';
import MockAdapter from 'axios-mock-adapter';
export const mock = new MockAdapter(axiosInstance)
try {
// 借助 localstorage 實現(xiàn) eruda 插件和 axios-mock-adapter 通信
const mockReqConf = JSON.parse(localStorage.getItem('_mock_req'))
if (mockReqConf && mockReqConf.mockId) {
mock.onGet(api.getOrderDetail).reply(config => {
// console.log('mock api', api.getOrderDetail)
return axiosInstance.get('https://mockrepository.zhuanzhuan.com/orderdetail?mockId=' + mockReqConf.mockId)
})
}
mock.onAny()
.passThrough()
const isProduction = process.env.NODE_ENV === 'production'
if (isProduction || (mockReqConf && mockReqConf.mockId === '')) {
// sessionStorage 實現(xiàn)開關(guān),如果沒有此配置,就重置設(shè)置的 mock 攔截
if (!sessionStorage.getItem('mock-adapter')) {
mock.restore()
}
}
} catch (error) {
console.log('mock adapter config error', error)
}
Eruda 插件
插件的目的是實現(xiàn)兩個功能,一個是總開關(guān),另一個是 mock 數(shù)據(jù)的展示和切換。
總開關(guān)借助 sessionStorage,webview 關(guān)閉 sessionStorage 數(shù)據(jù)清除,這樣避免了一進入頁面就是mock數(shù)據(jù),防止忘記關(guān)閉以及頻繁操作,需要的時候才打開。
Mock 數(shù)據(jù)的展示配置在一個配置文件中,公司有統(tǒng)一的配置中心,基于攜程 Apollo 實現(xiàn)。這個文件的作用是映射對應的狀態(tài)和 mock 數(shù)據(jù)來源,來源是統(tǒng)一的,所以只用參數(shù)區(qū)分即可。
示例如下:
[
{
"id": "/order/detail",
"list": [
{
"title": "正向流程",
"list": [
{
"title": "下單待發(fā)貨",
"id": "1-0-1"
},
{
"title": "寄賣下單",
"id": "1-1-0"
},
{
"title": "發(fā)貨運輸中",
"id": "1-2-0"
},
{
"title": "平臺質(zhì)檢",
"id": "1-3-0"
}
]
},
{
"title": "逆向流程",
"list": [
{
"title": "申請退回-退回中",
"id": "2-3-2"
}
]
}
]
}
]
id 用于標識當前頁面鏈接,是否有配置mock數(shù)據(jù),所以也支持配置多個頁面。
Eruda 插件的實現(xiàn)參考 eruda 官方文檔。
Eruda 如何寫插件[2] github.com/liriliri/er…
Eruda 工具庫[3] licia.liriliri.io/docs_cn.htm…
Eruda 插件寫法類比較像一個小的模板庫,eruda 提供了插件模板,綁定事件方式類似于 jQuery 語法,eruda 提供的 licia 工具庫均有對應方法,參考即可。
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.erudaPlugin = factory();
}
})(this, function() {
return function(eruda) {
var Tool = eruda.Tool,
util = eruda.util;
var Plugin = Tool.extend({
name: 'plugin',
init: function($el) {
this.callSuper(Tool, 'init', arguments);
this._style = util.evalCss(
[
'.eruda-dev-tools .eruda-tools .eruda-plugin {padding: 10px;}',
'.eruda-tip {padding: 10px; background: #fff; color: #263238;}'
].join('.eruda-dev-tools .eruda-tools .eruda-plugin ')
);
$el.html(
'<div class="eruda-tip">Put whatever you want here:)</div>'
);
},
show: function() {
this.callSuper(Tool, 'show', arguments);
},
hide: function() {
this.callSuper(Tool, 'hide', arguments);
},
destroy: function() {
this.callSuper(Tool, 'destroy', arguments);
util.evalCss.remove(this._style);
}
});
return new Plugin();
};
});
Mock 數(shù)據(jù)整理
這一部分其實是比較耗費體力的工作。需要整理每一個狀態(tài)的數(shù)據(jù),存儲起來。前面提到公司提供的一個接口平臺,基于去哪兒 YAPI 搭建,其提供了每個接口 mock 能力,我們添加 mock 數(shù)據(jù)即可。 前面配置文件中每一個狀態(tài)下的id其實就是 mock 數(shù)據(jù)的參數(shù)。
使用的時候,點選每一個狀態(tài),將狀態(tài)值寫入 localStorage 當中,刷新頁面。axios 請求時檢測是否有 localStorage 配置,有的話取出對應值,拼接到 YAPI mock 接口請求當中,獲取到 mock 數(shù)據(jù),然后頁面就是 mock 數(shù)據(jù)渲染出來的了。
初步嘗試后,可以讓我們在頁面開發(fā)過程中可以很方便得查看不同頁面下的頁面展現(xiàn),相比于之前的要么是查詢線上數(shù)據(jù),要么是通過數(shù)據(jù)構(gòu)造一步一步找到對應狀態(tài),都大大節(jié)省了時間,提升了效率。
同時對于產(chǎn)品和設(shè)計同學,也可以快速的找對對應頁面的樣子,方便產(chǎn)品對現(xiàn)有頁面進行調(diào)整,設(shè)計同學對頁面還原度進行檢查等等。
不足之處也有,就是數(shù)據(jù)的維護,現(xiàn)在每一個狀態(tài)下存儲的都是一份完整的數(shù)據(jù),如果某一部分調(diào)整了的話,那么所有的數(shù)據(jù)都要修改,數(shù)據(jù)越多,維護成本相對來說也越高。
以上是基于現(xiàn)有基礎(chǔ)能力搭建出來的一個簡單工具,當然還有更多改進空間,請多指教。
參考資料
[1] axios-mock-adapter: github.com/ctimmerm/ax…
[2] Eruda 如何寫插件: github.com/liriliri/er…
[3] Eruda 工具庫: licia.liriliri.io/docs_cn.htm…
以上就是JS技巧多狀態(tài)頁面中的mock方案詳解的詳細內(nèi)容,更多關(guān)于JS 多狀態(tài)頁面mock的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript設(shè)計模式之原型模式和適配器模式示例詳解
這篇文章主要為大家介紹了JavaScript 原型模式和適配器模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08

