摘要:監聽點贊事件廣播重點在這里我的動態頁面收到點贊變化通知進行更新操作監聽發布事件廣播重點在這里我的動態頁面收到發布動態通知進行更新操作重點在這里至此,我們在小程序中完美的實現了跨頁面組件多頁面數據同步。
導語:本文主要介紹在小程序中,多頁面之間如何保持數據同步
在很多的產品中,都會存在跨頁面間需要數據同步,如下示例:
為了更好的理解該場景,我們再詳細描繪一下:
本場景包括4個頁面:動態廣場、個人中心、我的動態、動態詳情
首先,進入動態廣場頁,請求加載數據,展示動態列表,其中,我們用綠色內陰影區分該條動態是“我的”,其他未加內陰影的表示是“別人的”;
然后,進入個人中心頁,請求加載數據,展示獲贊數量;
點擊我的動態,進入我的動態頁,請求加載數據,展示我的動態列表;
點擊其中一條動態,進入動態詳情頁,請求加載數據,進行點贊操作;
在第5步中,點贊成功后,回退到我的動態頁,可以看到該條動態點贊狀態和數量發生變化,已經同步;
再回到到個人中心頁,也可以看到獲贊數量發生變化,已經同步;
再回到動態廣場頁,也可以看到對應的一條動態點贊狀態和數量發生變化,已經同步;
下面我們來探討一下這個場景的實現,在此之前,我們先要了解在點贊時,該場景中各頁面的狀態及關系。
如上圖所示,當我們在點贊時,4個頁面都已經在是打開的(4個webview)。當我們點贊成功時,點擊左上解返回時,動態詳情頁的webview關掉,直接看到下一層webview,也就是我的動態頁,這個頁面是已經存在的。其他頁面也是如此。
那對于這些已經存在的頁面,我們應該如何同步更新數據呢?
當然,如果比較懶,可以直接在onShow的時候重新拉數據渲染頁面。但顯然這是非常低級、不可取也沒必要的做法。重新拉數據需要耗時,頁面重新渲染也會看到閃屏,關鍵是根本沒必要重新拉數據,因為數據發生了變化,前端是知道的。
所以我們可以這樣做,在動態詳情頁點贊成功時,保存一個數據到全局globalData中去,回到我的動態頁,在onShow中去檢測全局globalData中是否有點贊變化的數據,有的話,就讀取出來去更新相應的動態。
// 動態詳情頁js
onLike() {
...
success: () => {
App.globalData.like = {
fid: 10001,
likes: 1,
hasLike: true
}
}
}
// 我的動態頁js
onShow() {
if(App.globalData.like !== null) {
// 讀取globaldata.like數據去更新
this.doUpdata()
// 特別需要注意,更新完后,需要把globaldata.like清掉,不然下次onShow還會繼續走到該邏輯
App.globalData.like = null
}
}
這樣似乎可以達到我們的目的,無請求、純前端局部更新。
但這樣還存在一個問題,當我們再退回到個人中心頁時,要檢查下獲贊數量是否需要更新,以及回到動態廣場頁時,也要檢查點贊有沒有發生變化。但在這兩個頁面onShow去判斷App.globalData.like時,都已經檢測不到了,因為該數據已經在我的動態頁onShow中置為null了。
概括來說,在點贊時,只生產了一條數據,但有多個消費者,哪個頁面先把數據消費了,其他頁面也就無法檢測到數據了。
由此,我們想到那就使用EventBus來處理。
首先,我們自己實現一套簡單的EventBus。
源碼見:git.weixin.qq.com/xinyuanliu/…
在小程序啟動時,初始化EventBus:
const Event = require("/util/events.js").default
App({
events: null,
onLaunch(options) {
this.initEvents()
// doOtherThings
},
initEvents() {
this.events = new Event()
},
emitFeedsLike(data) {
this.events.emit("feedsLike", data)
},
emitPublishFeeds(data) {
this.events.emit("publishFeeds", data)
},
...
}
各個頁面在onLoad時,注冊監聽事件(在此以我的動態頁為例):
// 我的動態.js
const App = getApp()
Page({
data: {
list: []
},
onLoad: function (options) {
...
// 監聽點贊事件廣播
↓ 重點在這里 ↓
App.events.on("feedsLike", data => {
console.log("我的動態頁面收到點贊變化通知:", data)
// 進行更新操作
})
// 監聽發布事件廣播
↓ 重點在這里 ↓
App.events.on("publishFeeds", data => {
console.log("我的動態頁面收到發布動態通知:", data)
// 進行更新操作
})
},
...
})
然后在動態點贊時,發出事件通知。(這里一條動態是封裝成組件,不屬于某一個頁面,點贊事件也是封裝在組件內)
const App = getApp()
Component({
properties: {...},
methods: {
// 點贊
tapLike(e) {
let { likes, hasLike } = this.data
likes += (hasLike && -1 || 1)
hasLike = !hasLike
this.updateFeeds(likes, hasLike).then(() => {
this.setData({
likes,
hasLike
})
// 廣播事件
↓ 重點在這里 ↓
App.emitFeedsLike({
uid: this.data.uid,
fid: this.data.fid,
likes,
hasLike
})
})
},
...
}
})
這樣,我們便在小程序中實現了一套跨頁面數據同步的方案。
直觀上這已經非常完美的實現了我們的需求。但在小程序中存在一個與我們常規經驗不太一致的地方。那就是頁面在關掉后,它里面的對象并沒有銷毀,這點是因為小程序的邏輯層是共用一個進程。
因此,每次進入頁面,都會注冊一次監聽事件,而退出頁面后,該事件并不會銷毀。這樣的話,多次重復進入頁面,就會注冊多個重復事件,當事件發生時,就會執行多次響應。請仔細觀察下圖!
為了避免該現象出現,我們切記要在頁面的onUnload事件中,主動銷毀監聽事件。
Page({
eventsListener: {},
data: {
list: []
},
onLoad: function (options) {
...
// 監聽點贊事件廣播
↓ 重點在這里 ↓
this.eventsListener.feedsLike = App.events.on("feedsLike", data => {
console.log("我的動態頁面收到點贊變化通知:", data)
// 進行更新操作
})
// 監聽發布事件廣播
↓ 重點在這里 ↓
this.eventsListener.publishFeeds= App.events.on("publishFeeds", data => {
console.log("我的動態頁面收到發布動態通知:", data)
// 進行更新操作
})
},
↓ 重點在這里 ↓
onUnload() {
for (let i in this.eventsListener) {
App.events.remove(i, this.eventsListener[i])
}
},
...
})
至此,我們在小程序中完美的實現了跨頁面/組件、多頁面數據同步。
本文研究的demo均可以小程序中體驗,項目源碼:git.weixin.qq.com/xinyuanliu/…
歡迎交流討論。
下面是廣告時間
還沒有看夠?知名小程序跨端框架 Taro 的作者,面對面教你使用 React Hooks 來重構你的小程序,讓你更加優雅地進行小程序的數據管理,更有小程序云開發,企業級小程序開發實踐等硬核內容,要你好看!掃描下方二維碼查看具體詳情。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7289.html
摘要:從九月底內測到現在已經三個半月凌晨一點睡覺已經習以為常也正是這樣才讓無前端經驗的我做微信小程序開發并不感到費勁最近才開始接微信小程序的外包項目目前已經簽下了五份合同成品出了兩個加上轉給朋友做的正在談的算起來有十來個項目距離微信正式開放的時間 從九月底內測到現在已經三個半月.凌晨一點睡覺已經習以為常,也正是這樣,才讓無前端經驗的我做微信小程序開發并不感到費勁.最近才開始接微信小程序的外包...
摘要:從九月底內測到現在已經三個半月凌晨一點睡覺已經習以為常也正是這樣才讓無前端經驗的我做微信小程序開發并不感到費勁最近才開始接微信小程序的外包項目目前已經簽下了五份合同成品出了兩個加上轉給朋友做的正在談的算起來有十來個項目距離微信正式開放的時間 從九月底內測到現在已經三個半月.凌晨一點睡覺已經習以為常,也正是這樣,才讓無前端經驗的我做微信小程序開發并不感到費勁.最近才開始接微信小程序的外包...
摘要:傳統的網頁編程采用的三劍客來實現,在微信小程序中同樣有三劍客。觀察者模式不難實現,重點是如何在微信小程序中搭配其特有的生命周期來使用。交互事件傳統的事件傳遞類型有冒泡型與捕獲型,微信小程序中自然也有。 本文由作者鄒永勝授權網易云社區發布。 簡介為了更好的展示我們即時通訊SDK強悍的能力,網易云信IM SDK微信小程序DEMO的開發就提上了日程。用產品的話說就是: 云信 IM 小程序 S...
閱讀 1996·2021-11-19 09:40
閱讀 1952·2021-09-28 09:36
閱讀 2287·2021-09-22 10:02
閱讀 2730·2019-08-30 14:00
閱讀 1954·2019-08-29 15:31
閱讀 2902·2019-08-29 15:11
閱讀 2911·2019-08-29 13:04
閱讀 1084·2019-08-27 10:55