如何讓微信小程序頁面之間的通信不再變困難
一個開始
小程序開發(fā)者總會碰到各種頁面之間的通信問題,實現(xiàn)方式也五花八門,比如...
場景還原
首先這是一個電商小程序。
有這樣一個需求:
- 首頁某個地方要展示購物車商品數(shù)量。
- 當(dāng)我在其他頁面加購了商品,首頁數(shù)量刷新。
實現(xiàn)方式
方式一:onShow直接請求接口
Page({
onShow() {
// ...一些邏輯
// 后端請求新的購物車數(shù)量
this.requestCartNum();
}
})
不足: 每次onShow都要請求接口,浪費資源。
方式二:globalData存儲購物車數(shù)量,onShow中做刷新
// 主頁.js
Page({
onShow() {
// 在globalData獲取到購物車數(shù)據(jù)
let num = globalData.cartNum;
if (num !== this.data.cartNum) {
this.setData({
cartNum: num,
});
}
}
});
// 加購頁.js
Page({
// 加購后改變globalData的值
cartAdd(num) {
globalData.cartNum = globalData.cartNum + num;
}
})
方式三:加購后獲取首頁實例,調(diào)用首頁方法
// 首頁.js
Page({
onCartAdd(num) {
this.setData({
cartNum: this.data.cartNum + num,
});
},
});
// 加購頁.js
Page({
onCartAdd(num) {
// 加購后獲取到首頁的實例,調(diào)用首頁onCartAdd方法
let pages = getCurrentPages();
let curPage = pages[0];
curPage.onCartAdd(num);
}
})
不足:不確定能不能準確拿到首頁的實例,如果換做其他頁面就很難復(fù)用
方法四:事件訂閱與發(fā)布
// 首頁.js
Page({
onLoad() {
// 首頁監(jiān)聽事件
this.$bus.on('cart_add', (num) => {
this.setData({
cartNum: this.data.cartNum + num,
})
})
}
})
// 加購頁.js
Page({
// 加購成功后觸發(fā)cart_add事件
onCartAdd(num) {
this.$bus.emit('cart_add', num);
}
})
此方法用事件系統(tǒng),訂閱發(fā)布模式去做的處理。
以上幾種方法中最優(yōu)解決方案是方法四,利用事件的訂閱與發(fā)布,邏輯清晰兼容性好。但是都不可避免的不足是:每一個需要動態(tài)顯示購物數(shù)量的頁面都需要添加相同的邏輯代碼。
狀態(tài)管理方案
單頁應(yīng)用中最常用的就是組件之間的通信,由此誕生了不同的狀態(tài)存儲方案: react用redux, vue用vuex。他們的思路都是類似的。都有一個核心 store 存儲著一切要管理的狀態(tài)。
那么,其他框架可以,小程序也可以。以redux為例,實現(xiàn)一套簡單的狀態(tài)管理方案。
wxdux的實現(xiàn)
使用前提:有redux基礎(chǔ)
wxdux 類似與redux,以action來描述觸發(fā)的行為,reducer來描述state的變化。
1. 小程序入口中注冊
注冊store并添加到globalData中去
import {createStore} from './wxdux/index';
import reducer from './reducer';
const store = createStore(reducer);
App({
globalData: {
store,
},
});
2. reducer實現(xiàn)
寫法與redux類似,功能也類似。
const userReducer = (state = {}, action) => {
// ...
}
const postReducer = (state = [], action) => {
// ...
};
const reducers = {
user: userReducer,
posts: postReducer,
};
export default reducers;
3. 頁面中使用wxdux
connect方法會將小程序頁面實例與wxdux連接起來,必須提供$useState方法,該方法接收state,返回該頁面所需要的state
import {connect} from './wxdux/index';
Page(connect({
data: {
sex: '男',
},
onLoad() {
// ...
},
$useState(state) {
return {
name: state.name,
},
},
}))
4. wxml中使用name
<view>{{name}}</view>
5. 觸發(fā)store更新
使用dispatch方法,該方法接收一個對象作為參數(shù),該對象必須包含type字段表示action的類型,wxdux會根據(jù)此action更新state并且刷新所有使用name的視圖
import {dispatch} from './wxdux/index';
Page(connect({
// 某點擊事件觸發(fā),更新姓名為“張三”
onClick() {
const updateName = {
type: 'update_name',
name: '張三'
};
dispatch(updateName);
}
}))
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
JavaScript輸入框字數(shù)實時統(tǒng)計更新
這篇文章主要介紹了JavaScript輸入框字數(shù)實時統(tǒng)計更新,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
關(guān)于原生js中bind函數(shù)的簡單實現(xiàn)
下面小編就為大家?guī)硪黄P(guān)于原生js中bind函數(shù)的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08
layui table 列寬百分比顯示的實現(xiàn)方法
今天小編就為大家分享一篇layui table 列寬百分比顯示的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
Webpack常見靜態(tài)資源處理-模塊加載器(Loaders)+ExtractTextPlugin插件
這篇文章主要介紹了Webpack常見靜態(tài)資源處理-模塊加載器(Loaders)+ExtractTextPlugin插件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
javascript跨域方法、原理以及出現(xiàn)問題解決方法(詳解)
javascript出于安全方面的考慮,不允許跨域調(diào)用其他頁面的對象。但是在安全限制的同時也給注入iframe或是ajax應(yīng)用上帶來了不少麻煩。跨域簡單的理解就是因為javascript同源策略的限制,a.com域名下的js無法操作b.com 或者是c.a.com域名下的對象2015-08-08
學(xué)習(xí)JavaScript設(shè)計模式之模板方法模式
這篇文章主要為大家介紹了JavaScript設(shè)計模式中的模板方法模式,對JavaScript設(shè)計模式感興趣的小伙伴們可以參考一下2016-01-01

