一個開始
小程序開發者總會碰到各種頁面之間的通信問題,實現方式也五花八門,比如...
場景還原
首先這是一個電商小程序。
有這樣一個需求:
首頁某個地方要展示購物車商品數量。 當我在其他頁面加購了商品,首頁數量刷新。實現方式
方式一:onShow直接請求接口
Page({ onShow() { // ...一些邏輯 // 后端請求新的購物車數量 this.requestCartNum(); }})不足: 每次onShow都要請求接口,浪費資源。
方式二:globalData存儲購物車數量,onShow中做刷新
// 主頁.jsPage({ onShow() { // 在globalData獲取到購物車數據 let num = globalData.cartNum; if (num !== this.data.cartNum) { this.setData({ cartNum: num, }); } }});// 加購頁.jsPage({ // 加購后改變globalData的值 cartAdd(num) { globalData.cartNum = globalData.cartNum + num; }})方式三:加購后獲取首頁實例,調用首頁方法
// 首頁.jsPage({ onCartAdd(num) { this.setData({ cartNum: this.data.cartNum + num, }); },});// 加購頁.jsPage({ onCartAdd(num) { // 加購后獲取到首頁的實例,調用首頁onCartAdd方法 let pages = getCurrentPages(); let curPage = pages[0]; curPage.onCartAdd(num); }})不足:不確定能不能準確拿到首頁的實例,如果換做其他頁面就很難復用
方法四:事件訂閱與發布
// 首頁.jsPage({ onLoad() { // 首頁監聽事件 this.$bus.on('cart_add', (num) => { this.setData({ cartNum: this.data.cartNum + num, }) }) }})// 加購頁.jsPage({ // 加購成功后觸發cart_add事件 onCartAdd(num) { this.$bus.emit('cart_add', num); }})此方法用事件系統,訂閱發布模式去做的處理。
以上幾種方法中最優解決方案是方法四,利用事件的訂閱與發布,邏輯清晰兼容性好。但是都不可避免的不足是:每一個需要動態顯示購物數量的頁面都需要添加相同的邏輯代碼。
狀態管理方案
單頁應用中最常用的就是組件之間的通信,由此誕生了不同的狀態存儲方案: react用redux, vue用vuex。他們的思路都是類似的。都有一個核心 store 存儲著一切要管理的狀態。
那么,其他框架可以,小程序也可以。以redux為例,實現一套簡單的狀態管理方案。
wxdux的實現
使用前提:有redux基礎
wxdux 類似與redux,以action來描述觸發的行為,reducer來描述state的變化。
1. 小程序入口中注冊
注冊store并添加到globalData中去
import {createStore} from './wxdux/index';import reducer from './reducer';const store = createStore(reducer);App({ globalData: { store, },});
新聞熱點
疑難解答