如何讓微信小程序頁(yè)面之間的通信不再變困難
一個(gè)開始
小程序開發(fā)者總會(huì)碰到各種頁(yè)面之間的通信問題,實(shí)現(xiàn)方式也五花八門,比如...
場(chǎng)景還原
首先這是一個(gè)電商小程序。
有這樣一個(gè)需求:
- 首頁(yè)某個(gè)地方要展示購(gòu)物車商品數(shù)量。
- 當(dāng)我在其他頁(yè)面加購(gòu)了商品,首頁(yè)數(shù)量刷新。
實(shí)現(xiàn)方式
方式一:onShow直接請(qǐng)求接口
Page({
onShow() {
// ...一些邏輯
// 后端請(qǐng)求新的購(gòu)物車數(shù)量
this.requestCartNum();
}
})
不足: 每次onShow都要請(qǐng)求接口,浪費(fèi)資源。
方式二:globalData存儲(chǔ)購(gòu)物車數(shù)量,onShow中做刷新
// 主頁(yè).js
Page({
onShow() {
// 在globalData獲取到購(gòu)物車數(shù)據(jù)
let num = globalData.cartNum;
if (num !== this.data.cartNum) {
this.setData({
cartNum: num,
});
}
}
});
// 加購(gòu)頁(yè).js
Page({
// 加購(gòu)后改變globalData的值
cartAdd(num) {
globalData.cartNum = globalData.cartNum + num;
}
})
方式三:加購(gòu)后獲取首頁(yè)實(shí)例,調(diào)用首頁(yè)方法
// 首頁(yè).js
Page({
onCartAdd(num) {
this.setData({
cartNum: this.data.cartNum + num,
});
},
});
// 加購(gòu)頁(yè).js
Page({
onCartAdd(num) {
// 加購(gòu)后獲取到首頁(yè)的實(shí)例,調(diào)用首頁(yè)onCartAdd方法
let pages = getCurrentPages();
let curPage = pages[0];
curPage.onCartAdd(num);
}
})
不足:不確定能不能準(zhǔn)確拿到首頁(yè)的實(shí)例,如果換做其他頁(yè)面就很難復(fù)用
方法四:事件訂閱與發(fā)布
// 首頁(yè).js
Page({
onLoad() {
// 首頁(yè)監(jiān)聽事件
this.$bus.on('cart_add', (num) => {
this.setData({
cartNum: this.data.cartNum + num,
})
})
}
})
// 加購(gòu)頁(yè).js
Page({
// 加購(gòu)成功后觸發(fā)cart_add事件
onCartAdd(num) {
this.$bus.emit('cart_add', num);
}
})
此方法用事件系統(tǒng),訂閱發(fā)布模式去做的處理。
以上幾種方法中最優(yōu)解決方案是方法四,利用事件的訂閱與發(fā)布,邏輯清晰兼容性好。但是都不可避免的不足是:每一個(gè)需要?jiǎng)討B(tài)顯示購(gòu)物數(shù)量的頁(yè)面都需要添加相同的邏輯代碼。
狀態(tài)管理方案
單頁(yè)應(yīng)用中最常用的就是組件之間的通信,由此誕生了不同的狀態(tài)存儲(chǔ)方案: react用redux, vue用vuex。他們的思路都是類似的。都有一個(gè)核心 store 存儲(chǔ)著一切要管理的狀態(tài)。
那么,其他框架可以,小程序也可以。以redux為例,實(shí)現(xiàn)一套簡(jiǎn)單的狀態(tài)管理方案。
wxdux的實(shí)現(xiàn)
使用前提:有redux基礎(chǔ)
wxdux 類似與redux,以action來描述觸發(fā)的行為,reducer來描述state的變化。
1. 小程序入口中注冊(cè)
注冊(cè)store并添加到globalData中去
import {createStore} from './wxdux/index';
import reducer from './reducer';
const store = createStore(reducer);
App({
globalData: {
store,
},
});
2. reducer實(shí)現(xiàn)
寫法與redux類似,功能也類似。
const userReducer = (state = {}, action) => {
// ...
}
const postReducer = (state = [], action) => {
// ...
};
const reducers = {
user: userReducer,
posts: postReducer,
};
export default reducers;
3. 頁(yè)面中使用wxdux
connect方法會(huì)將小程序頁(yè)面實(shí)例與wxdux連接起來,必須提供$useState方法,該方法接收state,返回該頁(yè)面所需要的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方法,該方法接收一個(gè)對(duì)象作為參數(shù),該對(duì)象必須包含type字段表示action的類型,wxdux會(huì)根據(jù)此action更新state并且刷新所有使用name的視圖
import {dispatch} from './wxdux/index';
Page(connect({
// 某點(diǎn)擊事件觸發(fā),更新姓名為“張三”
onClick() {
const updateName = {
type: 'update_name',
name: '張三'
};
dispatch(updateName);
}
}))
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
JavaScript 語(yǔ)言精粹學(xué)習(xí)筆記
JavaScript建立在一些非常好的想法和少數(shù)非常壞的想法之上。2009-08-08
通過正則表達(dá)式實(shí)現(xiàn)表單驗(yàn)證是否為中文
正如標(biāo)題所言判斷一個(gè)輸入量是否為中文,通過正則表達(dá)式實(shí)現(xiàn),需要的朋友可以參考下2014-02-02
JavaScript檢測(cè)是否開啟了控制臺(tái)(F12調(diào)試工具)
通過js來檢測(cè)開發(fā)者工具是否打開,防止別人惡意調(diào)試我們的代碼,最近我發(fā)現(xiàn)還是有蠻多人去瀏覽那篇文章,所以這里再放出一段代碼,算是個(gè)升級(jí)版吧2020-10-10
關(guān)于Iframe父頁(yè)面與子頁(yè)面之間的相互調(diào)用
下面小編就為大家?guī)硪黄P(guān)于Iframe父頁(yè)面與子頁(yè)面之間的相互調(diào)用。小編覺得挺不錯(cuò)的,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧,祝大家游戲愉快哦2016-11-11

