第一次在公司裏負責作小程序,由於第一次作怕遇到大坑,因此用的原生開發。頁面數據共享比較經常使用,因此來研究研究。
1、上來建個文件夾把redux相關的代碼丟上去。git
//createStore.js export default function createStore(reducer, preloadedState, enhancer) { //放中間件用 其實就是在enhancer裏調用createStore 並修改dispatch if (enhancer && typeof enhancer === 'function') { return enhancer(createStore)(reducer, preloadedState) } //初始state賦值 let state = preloadedState; let listeners = []; const getState = () => state; //觸發動做 const dispatch = (action) => { state = reducer(state, action); listeners.forEach(listener => listener()); }; //添加監聽器,無非加些有setData的方法進去 const subscribe = (listener) => { listeners.push(listener); return () => { listeners = listeners.filter(l => l !== listener); } }; //初始化 dispatch({}); return { getState, dispatch, subscribe }; }
具體代碼能夠看代碼地址
對於redux不太理解的同窗能夠看看其它文章。有不少高手寫,我這個菜鳥就不寫了:)redux
2、把store 存到app.js裏小程序
import store from './store/index.js' import bindActionCreator from '/store/hcyRedux/bindActionCreator.js' App({ globalData: { store, bindActionCreator //方便dispatch } })
3、建actionpromise
// /action/page2 import * as types from '../action-types' //建立 action的函數 export default { change(obj) { return { type: 'page2/' + types.INPUT, payload: obj } }, promiseChange(obj) { return { type: 'page2/' + types.INPUT, payload: new Promise(function (resolve, reject) { setTimeout(function () { resolve(obj) }, 1000) }) } } } // /action/page1 import * as types from '../action-types' //建立 action的函數 export default { change(obj) { return { type: 'page1/' + types.INPUT, payload: obj} } }
4、建reducer微信
import * as types from '../action-types' const head = 'page2/' const defaultValue = { input1: 4, input2: 5, input3: 6 } export default function (state = defaultValue, action) { switch (action.type) { case head + types.INPUT: return { ...state, ...action.payload }; default: return state } }
這是page2的page1也差很少app
這樣子無論什麼頁面能夠經過app.globalData.store.getState()想怎麼取值均可以了。
固然每一個頁面的onload 和 onUnLoad 都必須添加和刪除監聽(就是setData)這樣dispatch 以後頁面纔會渲染。框架
這樣基本就完成了。但我不想每一個頁面都添加刪除監聽。能夠這麼幹。函數
// 本身封裝了一個mini-redux.js const app = getApp(); const store = app.globalData.store; //獲得一個{page1:{。。。},page2{。。。}}這樣一個對象 function getData (obj) { let res = {} obj.pages.forEach(x => { res[x] = store.getState()[x] }) return res } export default function (obj) { let listener = null; let res = {}; this.action = obj.action.map(x => app.globalData.bindActionCreator(x, store.dispatch)); this.store = store return { ...obj, data: getData(obj), onLoad: function () { listener = store.subscribe(() => { this.setData(getData(obj)) }) store.dispatch({}) obj.onLoad && obj.onLoad(); }, onUnload() { listener(); obj.onUnload && obj.onUnload(); } } }
page2頁面優化
<view class="page-section"> <view class="weui-cells__title">{{page2.input1}}</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input"> <input class="weui-input" placeholder="test" value="{{page2.input1}}" bindinput="bindKeyInput" data-key="input1" /> </view> </view> </view> <view class="page-section"> <view class="weui-cells__title">{{page2.input2}}</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input"> <input class="weui-input" placeholder="test" value="{{page2.input2}}" bindinput="bindKeyInput" data-key="input2" /> </view> </view> </view> <view class="page-section"> <view class="weui-cells__title">{{page2.input3}}</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input"> <input class="weui-input" placeholder="test" value="{{page2.input3}}" bindinput="bindKeyInput" data-key="input3" /> </view> </view> </view> <text>{{page1.input1}}</text> <navigator url="/pages/page2/page2"> <button type="primary"> 2 </button> </navigator>
page2.jsui
import actions1 from '../../store/actions/page1.js' import actions2 from '../../store/actions/page2.js' import V from '../../utils/mini-redux.js' const page = {} Page(V.call(page,{ action: [actions1, actions2], //定義好用那些action pages:['page1', 'page2'], //定義好須要用那些store 是在reducer/index.js 定義的 bindKeyInput(e) { //action[0] 就是actions1 page.action[0].change({ [e.target.dataset.key]: e.detail.value }); page.action[1].promiseChange({ [e.target.dataset.key]: e.detail.value }); }, onShow() { console.log('show2') }, onLoad () { console.log('load2') } }))
具體代碼能夠看代碼地址
仍是有些問題 每次dispatch 會觸發頁面棧的全部頁面的監聽,頁面能夠直接setData store 等等。這些地方應該還能夠優化。