用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

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

如何處理小程序獨立分包的數據共享問題

Rolan 2020-1-10 00:55

小程序2.3.0版本開始支持獨立分包。對于短期的活動落地頁,我們會選擇使用獨立分包,這可以大大提升活動落地頁的加載速度。 但與此同時,由于獨立分包中不能依賴主包和其他分包中的內容,獨立分包的使用也帶來了一些 ...

小程序2.3.0版本開始支持獨立分包。對于短期的活動落地頁,我們會選擇使用獨立分包,這可以大大提升活動落地頁的加載速度。

但與此同時,由于獨立分包中不能依賴主包和其他分包中的內容,獨立分包的使用也帶來了一些數據共享問題。

遇到的問題

公用數據處理復雜

對于頁面間的公用數據,我們原本的處理方式是將數據掛在App對象上。但引入了獨立分包后,判斷的邏輯就變得復雜了。

例如,我們想設計一個計數器counter,能夠在小程序的各個地方調用。我們將結果記錄在app.globalData.count,這時候需要分三種場景考慮:

  1. 主包和普通分包頁面中,通過getApp()來獲取App對象;
  2. 在App對象中,通過this來獲取App對象;
  3. 在獨立分包或App對象注冊前,通過getApp({ allowDefault: true })來獲取App對象(新的邏輯);

另外,對于3的情況,由于App對象可能未初始化,還要判斷globalData、count屬性是否存在。

事件被重復綁定

通過wx.onError、wx.onPageNotFound等方法可以監控小程序的運行情況,我們把這些能力封裝在npm包中。

export function report() {
  // 各種處理邏輯
  // ....
}

wx.onError(report);
復制代碼

當獨立分包和主包都引入了這個npm包,而npm包中調用wx.onXXXX方法進行了綁定,我們可以想到,當用戶在獨立分包和主包頁面之間跳轉時,事件的處理函數會被綁定不止一次(主包一次,每個獨立分包一次)。

解決思路

  1. 對于需要在主包、獨立分包公用數據的情況,我們考慮將不同場景下讀寫app對象的能力封裝起來,這類似于一個SessionStorage,我們可以在任意場景操作SessionStorage里的公用數據,而數據會在小程序從冷啟動到銷毀的運行過程中一直保留。

  2. 對于事件重復綁定的問題,我們使用sessionStorage中的一個key來加鎖。實現一個once方法,保證同一個key的邏輯只執行一次,通過如下的方式來調用

    export function report() {
      // 各種處理邏輯
      // ....
    }
    
    once('_wx_onerror_key_', () => { wx.onError(report); });
    復制代碼

具體實現

  1. 為了不與原有的globalData沖突,我們使用一個新的BASIC_KEY,作為App對象上的屬性名,來存儲sessionStorage的內容。
  2. 默認以getApp({ allowDefault: true })獲取App對象,為了滿足在App()內調用時也能取到正確的App對象,我們可以在App.onLaunch方法時將this傳入sessionStorage.setApp(this)。
  3. 暴露的api對齊瀏覽器的sessionStorage,實現如下:
const BASIC_KEY = '_imwxutils_sessionStorageData_';
let app = getApp({ allowDefault: true }) || {};
app[BASIC_KEY] = app[BASIC_KEY] || {};

export function setApp(customApp) {
  customApp[BASIC_KEY] = customApp[BASIC_KEY] || app[BASIC_KEY] || {};
  app = customApp;
}

export function setItem(key, value) {
  app[BASIC_KEY][key] = value;
}

export function getItem(key) {
  return app[BASIC_KEY][key];
}

export function removeItem(key) {
  app[BASIC_KEY][key] = null;
}

export function clear() {
  app[BASIC_KEY] = {};
}

復制代碼

基于sessionStorage我們又可以實現once方法:

import * as sessionStorage from './session-storage';

const ONCE_BASIC_KEY = '_imwxutils_once_record_';
/**
 * 全局只執行一次的方法
 */
function once(key, func) {
  if (!key) {
    return;
  }
  const record = sessionStorage.getItem(ONCE_BASIC_KEY) || {};

  if (record[key]) { // 之前執行過了
    return;
  }
  record[key] = true;
  sessionStorage.setItem(ONCE_BASIC_KEY, record);
  func();
}
復制代碼

以上,通過實現sessionStorage和once方法,我們解決了獨立分包與主包之間數據共享以及事件綁重復定的問題。

歡迎交流

鮮花
鮮花
雞蛋
雞蛋
分享至 : QQ空間
收藏
原作者: 饅頭點心 來自: 掘金
梦幻单人赚钱方法 姚记棋牌所有app 陕西星悦麻将 豪利棋牌68uc版本 真人街机捕鱼 金蟾捕鱼 打麻将就可以赚钱的游戏 网上赚钱软件是真的 首次公开发行股票承 湖南幸运赛车开奖结果爱彩人 财神捕鱼天下第一 熊猫麻将电脑版