用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

2018年10月11日湖人vs勇士录像:利用watch在小程序中實現全局狀態共享

湖人vs爵士季后赛 www.nbgeh.club Rolan 2019-6-4 00:43

在之前開發微信小程序的時候,獲取用戶信息、openid還有地理位置這些信息的時候,都是采用Promise的方式異步獲取,但是這樣的話在頁面和App.js中都獲取就可能造成請求重復的問題。比如為了在每個頁面都能獲取到這些 ...

在之前開發微信湖人vs爵士季后赛的時候,獲取用戶信息、openid還有地理位置這些信息的時候,都是采用 Promise 的方式異步獲取,但是這樣的話在頁面和App.js中都獲取就可能造成 請求重復 的問題。

比如為了在每個頁面都能獲取到這些共享信息,都會選擇在App.js中進行獲取,然后在頁面級進行獲取,這兩次獲取的時間間隔較小時就可能導致前一個請求還未獲取到數據,后一個請求就會再次進行獲取,這樣就產生了兩次請求。

還有一個問題就是書寫麻煩(雖然也能通過async await簡化),比如

onLoad() {
    app.getUserInfo()
    .then(userInfo => {
        
    }).catch(err => { /* 錯誤處理 */ });
    
    // 如果同時需要userInfo和openid,可能就是如下形式:
    Promise.all([app.getUserInfo(), app.getOpenid()])
    .then(res => {
        
    }).catch(err => { /* 錯誤處理 */ });
}
復制代碼

正好周末的時候突然想到了vue的watch語法,利用一些相關的知識,就可以解決這個麻煩的問題了。

解決思路

雙向綁定

vue的雙向綁定原理,3.0將會采用Proxy監聽數據變化,不過考慮到小程序這邊的Proxy兼容性我不知道,所以采用了2.0的Object.defineProperty來監聽數據的變化。

主要還是攔截設置的操作,在進行賦值時,將新舊值通知至監聽者。

觀察者模式

在頁面級的onLoad 監聽 app.globalData 各個鍵名的事件 ,而在app.js的onLoad中則使用Object.defineProperty重新定義app.globalData,這樣一旦app.globalData相應的鍵值發生了變化,就會通知監聽的頁面該值發生了變化。

??榛囊?/h3>

觀察者模式導出的是一個對象(類實例),而不是一個類,所以在導入的時候這個對象是共享的,就可以通過這個對象將app.js和其他頁面聯系起來。

至于??榧釉氐氖抵?,ES6??榧釉氐幕?,與CommonJS??橥耆煌?。感興趣的可以去看看這個。

封裝Page

小程序的Page函數本身是不支持watch,但是我們可以自定義一個函數,進行參數合并就可以了。

在頁面onLoad時先遍歷watch屬性,對app.globalData進行監聽,可以參考vue的watch用法。

頁面onUnload時就會進行銷毀,此時也應該取消監聽,這些我都封裝過了,不用手動處理了。

有了這些思路,用不了多久,一個雛形就出來了,經過手動測試,感覺沒什么問題,我就發布到npm了,大家感興趣的可以安裝體驗一下。

安裝

npm i wx-watch -S --production
復制代碼

使用

// app.js
var { watchData, } = require('/miniprogram_npm/wx-watch/index.js');

App({
  onLaunch() {
    this.watchData(); /* 監聽this.globalData的變化,并觸發事件,其他頁面監聽的值必須在globalData中預先定義,否則無法監聽 */
  },
  watchData,
  globalData: {
    userInfo: null,
  }
});

// 其他需要監聽globalData的頁面.js
var { getPage } = require('../../miniprogram_npm/wx-watch/index.js');
const app = getApp();

/**
 * getPage(頁面參數,app) app必傳,因為封裝的時候訪問不到,就只能傳參了
*/
getPage({
  watch: {
    userInfo(userInfo, oldUserInfo) {
      console.log(`來自app.glodalData的userInfo`);
    }
  },
  // 其他參數
}, app)
復制代碼

github: github.com/ma125120/wx…

要是用的還行,歡迎star。

要是有問題,歡迎提交issue。

分享至 : QQ空間
收藏
原作者: ma125120 來自: 掘金