一個用于小程序和輕量級H5應(yīng)用的狀態(tài)管理工具, 使用方法是一個簡化版本的Redux。之所以是適用于輕量級應(yīng)用,主要是因為沒有實(shí)現(xiàn)組件間的數(shù)據(jù)共享。因此不適合于復(fù)雜,龐大的前端應(yīng)用。
如果你也和我有同樣的困惑,那么你就該嘗試一下:
拷貝 /mp-redux/index.js文件到項目中引入即可。開包即用。
懶
const mpState = require('./mp-redux/index.js'); const userInfo = require('./model/userinfo.js'); const logs = require('./model/logs.js'); mpState.createStore({ logs, // 這些model 就是redux的reduce,必須是純函數(shù),并且需要返回一個純對象 userInfo // 這些model 就是redux的reduce,必須是純函數(shù),并且需要返回一個純對象 }, 'onShow') // 第二個參數(shù)是劫持的生命周期函數(shù),這是為了解決不同平臺的差異性問題導(dǎo)致的。后期會考慮優(yōu)化 復(fù)制代碼
// model 就是數(shù)據(jù)模型,是根據(jù)業(yè)務(wù)而來的 // model/userinfo.js const actions = require('./../action/logs.js'); // 這里同樣采用了redux的action機(jī)制 const initState = { logs: [] } module.exports = function (state = initState, action = {}) { const newState = { ...state }; switch (action.type) { case actions.addLogs: const now = new Date(); newState.logs.push({ time: now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds(), value: action.data }); return newState; case actions.clearLogs: newState.logs = []; return newState; default: return newState; } } // action/userinfo.js module.exports = { addLogs: 'LOGS_ADD', clearLogs: 'LOGS_CLEAR' } 復(fù)制代碼 |
// 使用connect來注入需要訂閱的狀態(tài),并且mp-redux會在頁面對象中自動注入dispatch方法 const mpState = require('./../../mp-redux/index.js'); const util = require('../../utils/util.js'); const logActions = require('./../../action/logs.js'); Page(mpState.connect((state) => { return { userInfo: state.userInfo.userInfo, logs: state.logs.logs } }, { // 在這里所有的業(yè)務(wù)數(shù)據(jù)都保存在store中,所以頁面如果只有業(yè)務(wù)數(shù)據(jù)的話,是不需要data屬性的。 clearLogs() { this.dispatch({ // 通過dispatch方法來發(fā)出action,從而更新store中的數(shù)據(jù) type: logActions.clearLogs }) } })) 復(fù)制代碼 |
// 不要吐槽,,,,,,我第一次寫測試用例。(-_-) const actions = require('./../action/logs.js'); const model = require('./../model/logs.js'); test('1. init logs data', () => { expect(model()).toEqual({ logs: [] }) }) test('2. add new log into empty logs', () => { const newState = model(undefined, { type: actions.addLogs, data: "Test new log" }); expect({ value: newState.logs[0].value, len: newState.logs.length }).toEqual({ value: "Test new log", len: 1 }); }) test('3. add new log into logs', () => { const newState = model({logs: [{time: '00:00:00', value: 'the first log'}]}, { type: actions.addLogs, data: "the second log" }); expect({ log1: newState.logs[0].value, log2: newState.logs[1].value, len: newState.logs.length }).toEqual({ log1: "the first log", log2: "the second log", len: 2 }); }) test('4. clear all logs', () => { const newState = model({ logs: [ { time: '00:00:00', value: 'log1' }, { time: '00:00:00', value: 'log2' } ] }, { type: actions.clearLogs }); expect({ len: newState.logs.length }).toEqual({ len: 0 }); }) 復(fù)制代碼 |
因為互聯(lián)網(wǎng)產(chǎn)品都是toC業(yè)務(wù),UI基本上每天都在變化,但是業(yè)務(wù)的變化其實(shí)是很小的。我們通過將業(yè)務(wù)建模,在前端構(gòu)建業(yè)務(wù)數(shù)據(jù)模型。而這些模型是可以預(yù)知的。因此也就可測試。
而對于一些互聯(lián)網(wǎng)產(chǎn)品,前端測試是一件非常繁瑣而復(fù)雜的事情。因此這個簡單的方案大大的降低了前端代碼變動引起的風(fēng)險,而增加的工作量也并不是很大??梢砸欢ǔ潭壬辖档蜆I(yè)務(wù)代碼的回歸測試成本。