這篇文章給大家分享的是有關(guān)微信小程序中頁面間通信的方式有哪些的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
站在用戶的角度思考問題,與客戶深入溝通,找到平原網(wǎng)站設(shè)計(jì)與平原網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請(qǐng)域名、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋平原地區(qū)。
PageModel(頁面模型)對(duì)小程序而言是很重要的一個(gè)概念,從app.json中也可以看到,小程序就是由一個(gè)個(gè)頁面組成的。

如上圖,這是一個(gè)常見結(jié)構(gòu)的小程序:首頁是一個(gè)雙Tab框架PageA和PageB,子頁面pageB, PageC。
讓我們假設(shè)這樣一個(gè)場(chǎng)景:首頁P(yáng)ageA有一個(gè)飄數(shù),當(dāng)我們從PageA新開PageC后,做一些操作,再回退到PageA的時(shí)候,這個(gè)飄數(shù)要刷新。很顯然,這需要在PageC中做操作時(shí),能通知到PageA,以便PageA做相應(yīng)的聯(lián)動(dòng)變化。
這里的通知,專業(yè)點(diǎn)說就是頁面通信。所謂通信,u3認(rèn)為要滿足下面兩個(gè)條件:
激活對(duì)方的一個(gè)方法調(diào)用
能夠向被激活的方法傳遞數(shù)據(jù)
本文將根據(jù)項(xiàng)目實(shí)踐,結(jié)合小程序自身特點(diǎn),就小程序頁面間通信方式作一個(gè)探討與小結(jié)。
通信分類
按頁面層級(jí)(或展示路徑)可以分為:
兄弟頁面間通信。如多Tab頁面間通信,PageA,PageB之間通信
父路徑頁面向子路徑頁面通信,如PageA向PageC通信
子路徑頁面向父路徑頁面通信,如PageC向PageA通信
按通信時(shí)激活對(duì)方方法時(shí)機(jī),又可以分為:
延遲激活,即我在PageC做完操作,等返回到PageA再激活PageA的方法調(diào)用
立即激活,即我在PageC做完操作,在PageC激活PageA的方法調(diào)用
方式一:onShow/onHide + localStorage
利用onShow/onHide激活方法,通過localStorage傳遞數(shù)據(jù)。大概邏輯如下
// pageA
let isInitSelfShow = true;
Page({
data: {
helloMsg: 'hello from PageA'
},
onShow() {
// 頁面初始化也會(huì)觸發(fā)onShow,這種情況可能不需要檢查通信
if (isInitSelfShow) return;
let newHello = wx.getStorageSync('__data');
if (newHello) {
this.setData({
helloMsg: newHello
});
// 清隊(duì)上次通信數(shù)據(jù)
wx.clearStorageSync('__data');
}
},
onHide() {
isInitSelfShow = false;
},
goC() {
wx.navigateTo({
url: '/pages/c/c'
});
}
});// pageC
Page({
doSomething() {
wx.setStorageSync('__data', 'hello from PageC');
}
});優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,容易理解
缺點(diǎn):如果完成通信后,沒有即時(shí)清除通信數(shù)據(jù),可能會(huì)出現(xiàn)問題。另外因?yàn)橐蕾噇ocalStorage,而localStorage可能出現(xiàn)讀寫失敗,從面造成通信失敗
注意點(diǎn):頁面初始化時(shí)也會(huì)觸發(fā)onShow
方式二:onShow/onHide + 小程序globalData
同方式一一樣,利用onShow/onHide激活方法,通過讀寫小程序globalData完成數(shù)據(jù)傳遞
// PageA
let isInitSelfShow = true;
let app = getApp();
Page({
data: {
helloMsg: 'hello from PageA'
},
onShow() {
if (isInitSelfShow) return;
let newHello = app.$$data.helloMsg;
if (newHello) {
this.setData({
helloMsg: newHello
});
// 清隊(duì)上次通信數(shù)據(jù)
app.$$data.helloMsg = null;
}
},
onHide() {
isInitSelfShow = false;
},
goC() {
wx.navigateTo({
url: '/pages/c/c'
});
}
});// PageC
let app = getApp();
Page({
doSomething() {
app.$$data.helloMsg = 'hello from pageC';
}
});優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,實(shí)現(xiàn)理解。因?yàn)椴蛔x寫localStorage,直接操作內(nèi)存,所以相比方式1,速度更快,更可靠
缺點(diǎn):同方式1一樣,要注意globalData污染
方式三:eventBus(或者叫PubSub)方式
這種方式要先實(shí)現(xiàn)一個(gè)PubSub,通過訂閱發(fā)布實(shí)現(xiàn)通信。在發(fā)布事件時(shí),激活對(duì)方方法,同時(shí)傳入?yún)?shù),執(zhí)行事件的訂閱方法

/* /plugins/pubsub.js
* 一個(gè)簡(jiǎn)單的PubSub
*/
export default class PubSub {
constructor() {
this.PubSubCache = {
$uid: 0
};
}
on(type, handler) {
let cache = this.PubSubCache[type] || (this.PubSubCache[type] = {});
handler.$uid = handler.$uid || this.PubSubCache.$uid++;
cache[handler.$uid] = handler;
}
emit(type, ...param) {
let cache = this.PubSubCache[type],
key,
tmp;
if(!cache) return;
for(key in cache) {
tmp = cache[key];
cache[key].call(this, ...param);
}
}
off(type, handler) {
let counter = 0,
$type,
cache = this.PubSubCache[type];
if(handler == null) {
if(!cache) return true;
return !!this.PubSubCache[type] && (delete this.PubSubCache[type]);
} else {
!!this.PubSubCache[type] && (delete this.PubSubCache[type][handler.$uid]);
}
for($type in cache) {
counter++;
}
return !counter && (delete this.PubSubCache[type]);
}
}//pageA
let app = getApp();
Page({
data: {
helloMsg: 'hello from PageA'
},
onLoad() {
app.pubSub.on('hello', (number) => {
this.setData({
helloMsg: 'hello times:' + number
});
});
},
goC() {
wx.navigateTo({
url: '/pages/c/c'
});
}
});//pageC
let app = getApp();
let counter = 0;
Page({
doSomething() {
app.pubSub.emit('hello', ++counter);
},
off() {
app.pubSub.off('hello');
}
});缺點(diǎn):要非常注意重復(fù)綁定的問題
方式四:gloabelData watcher方式
前面提到方式中,我們有利用globalData完成通信。現(xiàn)在數(shù)據(jù)綁定流行,結(jié)合redux單一store的思想,如果我們直接watch一個(gè)globalData,那么要通信,只需修改這個(gè)data值,通過water去激活調(diào)用。同時(shí)修改的data值,本身就可以做為參數(shù)數(shù)據(jù)。
為了方便演示,這里使用oba這個(gè)開源庫做為對(duì)象監(jiān)控庫,有興趣的話,可以自己實(shí)現(xiàn)一個(gè)。
//pageA
import oba from '../../plugin/oba';
let app = getApp();
Page({
data: {
helloMsg: 'hello from PageA'
},
onLoad() {
oba(app.$$data, (prop, newvalue, oldValue) => {
this.setData({
helloMsg: 'hello times: ' + [prop, newvalue, oldValue].join('#')
});
});
},
goC() {
wx.navigateTo({
url: '/pages/c/c'
});
}
});//pageC
let app = getApp();
let counter = 0;
Page({
doSomething() {
app.$$data.helloTimes = ++counter;
}
});優(yōu)點(diǎn):數(shù)據(jù)驅(qū)動(dòng),單一數(shù)據(jù)源,便于調(diào)試
缺點(diǎn):重復(fù)watch的問題還是存在,要想辦法避免
方式五:通過hack方法直接調(diào)用通信頁面的方法
直接緩存頁面PageModel, 通信時(shí),直接找到要通信頁面的PageModel,進(jìn)而可以訪問通信頁面PageModel所有的屬性,方法。簡(jiǎn)直不能太cool,感謝小組內(nèi)小伙伴發(fā)現(xiàn)這么amazing的方式。有人肯定會(huì)問了,怎么拿到這個(gè)所有的PageModel呢。其它很簡(jiǎn)單,每個(gè)頁面有onLoad方法,我們?cè)谶@個(gè)事件中,把this(即些頁面PageModel)緩存即可,緩存時(shí)用頁面路徑作key,方便查找。那么頁面路徑怎么獲取呢,答案就是page__route__這個(gè)屬性
// plugin/pages.js
// 緩存pageModel,一個(gè)簡(jiǎn)要實(shí)現(xiàn)
export default class PM {
constructor() {
this.$$cache = {};
}
add(pageModel) {
let pagePath = this._getPageModelPath(pageModel);
this.$$cache[pagePath] = pageModel;
}
get(pagePath) {
return this.$$cache[pagePath];
}
delete(pageModel) {
try {
delete this.$$cache[this._getPageModelPath(pageModel)];
} catch (e) {
}
}
_getPageModelPath(page) {
// 關(guān)鍵點(diǎn)
return page.__route__;
}
}// pageA
let app = getApp();
Page({
data: {
helloMsg: 'hello from PageA'
},
onLoad() {
app.pages.add(this);
},
goC() {
wx.navigateTo({
url: '/pages/c/c'
});
},
sayHello(msg) {
this.setData({
helloMsg: msg
});
}
});//pageC
let app = getApp();
Page({
doSomething() {
// 見證奇跡的時(shí)刻
app.pages.get('pages/a/a').sayHello('hello u3xyz.com');
}
});優(yōu)點(diǎn):一針見血,功能強(qiáng)大,可以向要通信頁面做你想做的任何事。無需要綁定,訂閱,所以也就不存在重復(fù)的情況
缺點(diǎn):使用了__route__這個(gè)hack屬性,可能會(huì)有一些風(fēng)險(xiǎn)
感謝各位的閱讀!關(guān)于“微信小程序中頁面間通信的方式有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
本文名稱:微信小程序中頁面間通信的方式有哪些
分享鏈接:http://chinadenli.net/article34/jiihse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司、用戶體驗(yàn)、自適應(yīng)網(wǎng)站、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)