小程序開發者總會碰到各類頁面之間的通訊問題,實現方式也五花八門,好比...vue
首先這是一個電商小程序。react
有這樣一個需求:git
實現方式github
Page({ onShow() { // ...一些邏輯 // 後端請求新的購物車數量 this.requestCartNum(); } })
不足: 每次onShow都要請求接口,浪費資源。vuex
// 主頁.js
Page({
onShow() {
// 在globalData獲取到購物車數據
let num = globalData.cartNum;
if (num !== this.data.cartNum) {
this.setData({
cartNum: num,
});
}
}
});
// 加購頁.js
Page({
// 加購後改變globalData的值
cartAdd(num) {
globalData.cartNum = globalData.cartNum + num;
}
})
// 首頁.js Page({ onCartAdd(num) { this.setData({ cartNum: this.data.cartNum + num, }); }, }); // 加購頁.js Page({ onCartAdd(num) { // 加購後獲取到首頁的實例,調用首頁onCartAdd方法 let pages = getCurrentPages(); let curPage = pages[0]; curPage.onCartAdd(num); } })
不足:不肯定能不能準確拿到首頁的實例,若是換作其餘頁面就很難複用redux
// 首頁.js Page({ onLoad() { // 首頁監聽事件 this.$bus.on('cart_add', (num) => { this.setData({ cartNum: this.data.cartNum + num, }) }) } }) // 加購頁.js Page({ // 加購成功後觸發cart_add事件 onCartAdd(num) { this.$bus.emit('cart_add', num); } })
此方法用事件系統,訂閱發佈模式去作的處理。小程序
以上幾種方法中最優解決方案是方法四,利用事件的訂閱與發佈,邏輯清晰兼容性好。可是都不可避免的不足是:每個須要動態顯示購物數量的頁面都須要添加相同的邏輯代碼。後端
單頁應用中最經常使用的就是組件之間的通訊,由此誕生了不一樣的狀態存儲方案: react用redux, vue用vuex。他們的思路都是相似的。都有一個核心 store
存儲着一切要管理的狀態。框架
那麼,其餘框架能夠,小程序也能夠。以redux爲例,實現一套簡單的狀態管理方案。post
使用前提:有redux基礎
wxdux 相似與redux,以action來描述觸發的行爲,reducer來描述state的變化。
註冊store並添加到globalData中去
import {createStore} from './wxdux/index'; import reducer from './reducer'; const store = createStore(reducer); App({ globalData: { store, }, });
寫法與redux相似,功能也相似。
const userReducer = (state = {}, action) => { // ... } const postReducer = (state = [], action) => { // ... }; const reducers = { user: userReducer, posts: postReducer, }; export default reducers;
connect方法會將小程序頁面實例與wxdux鏈接起來,必須提供$useState方法,該方法接收state,返回該頁面所須要的state
import {connect} from './wxdux/index'; Page(connect({ data: { sex: '男', }, onLoad() { // ... }, $useState(state) { return { name: state.name, }, }, }))
<view>{{name}}</view>
使用dispatch方法,該方法接收一個對象做爲參數,該對象必須包含type字段表示action的類型,wxdux會根據此action更新state而且刷新全部使用name的視圖
import {dispatch} from './wxdux/index'; Page(connect({ // 某點擊事件觸發,更新姓名爲「張三」 onClick() { const updateName = { type: 'update_name', name: '張三' }; dispatch(updateName); } }))