用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

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

2017年12月19日湖人vs勇士:小程序頁面通信解決方案

湖人vs爵士季后赛 www.nbgeh.club Rolan 2019-8-14 00:18

小程序頁面通信 解決方案有很多,本地緩存、全局變量、手寫訂閱發布。本文著重介紹另一個解決方案,就是暫存當前頁面的執行上下文,然后在另一個頁面調用。 github地址 簡介 主要是想解決小程序跨頁面通信的問題,我 ...

湖人vs爵士季后赛頁面通信

解決方案有很多,本地緩存、全局變量、手寫訂閱發布。本文著重介紹另一個解決方案,就是暫存當前頁面的執行上下文,然后在另一個頁面調用。

github地址

簡介

主要是想解決小程序跨頁面通信的問題,我想用一種最簡單,最優雅,并且讓用戶可以很方便的使用的小工具。

安裝

將 store.js 文件放在 utils 文件夾( 可以是任意文件夾 )下即可,然后引入文件。

引入

import store from "path/store.js"
復制代碼

使用

推薦的使用流程是這樣的,比如 b 頁面需要用到 a 頁面里的數據。

  1. 先在 a 頁面引入 store 然后在 onload 方法里使用 store.addData(this, "a") 來將當前頁面的執行上下文加載到 store 的數據池里。
  2. 在 b 頁面引入 store ,然后就可以在 b 頁面通過 store.a.數據名 來獲取相應數據的值,也可以通過 store.a.數據名 = "balabala" 來給相應的數據賦值,這里注意,這樣的賦值方式是響應式的,不需要通過 setData 函數來賦值就可以達到效果。(暫未實現 setData 方式賦值,推薦使用直接賦值)

方法簡介

  • 添加頁面數據

    store.addData( context, name )
    復制代碼

    參數說明:

    • context

      執行上下文,也就是當前頁面的 this

    • name

      命名當前頁面,也就是在別的頁面取值的時候 store.name.屬性,默認值為當前頁面的路徑

  • 移除頁面數據

    store.removeData( name )
    復制代碼

    參數說明

    • name

      希望刪除的頁面數據的名字

  • 獲取數據

    let value = store.頁面name.屬性
    復制代碼

    這樣既可獲取數據,后臺是用代理封裝了數據池,從而方便用戶使用

  • 修改數據

    store.頁面name.屬性 = value
    復制代碼

    這樣賦值即可,后臺使用的依然是封裝的 setData

  • 檢測屬性是否存在

    property in store.頁面name
    復制代碼

    代碼

    /**
       * @author xiaoheng
       * @time 2019/8/1
       * @github https://github.com/xiaoheng21
       * @tip 還在找工作,有機會望告知,坐標北京
       */
    /**
       * 狀態管理類
       * @constructor 構造函數
       * @_data  內部數據,用來保存頁面數據
       * @addData 添加頁面數據的方法
       * @removeData 移除不需要的頁面數據,減小內存壓力
       */
      class Store {
        constructor() {
          this._data = {};
        }
      
        /**
         * 向數據池里添加數據
         * @param { Object<this> } context 保存當前頁面的執行上下文,也就是當前頁面的 this
         * @param { String } name 當前頁面數據的名字,用于在別的頁面讀取數據,默認值為當前頁面的路徑
         */
        addData(context, name) {
          // 如果傳了 name 就用傳過來的,如果未傳就用頁面路徑
          let routeName = name ? name : context.route;
          //設置代理,用于簡化操作
          let proxyContext = new Proxy(context, {
            // 獲取數據,如果數據在外層,返回外層數據
            get: function(context, property) {
              if (property in context) {
                return context[property];
              } else {
                // 如果外層找不到數據, 就在 "this.data" 里找,若有,返回數據
                if (property in context.data) {
                  return context.data[property];
                } else {
                  //若沒有,報錯
                  console.error(`${name}頁面沒有此屬性`);
                }
              }
            },
            // 改變數據, 封裝 "this.setData", 簡化操作
            set: function(context, property, value) {
              context.setData({
                [property]: value
              });
              return true;
            },
            // 判斷數據是否存在
            has: function(context, property) {
              return property in context.data;
            }
          });
          // 將代理對象添加進數據池
          this._data[routeName] = proxyContext;
        }
      
        /**
         * 從數據池里移除頁面數據
         * @param { String } name 需要移除的頁面的名字
         */
        removeData(name) {
          if (name in this._data) {
            delete this._data[name];
          } else {
            console.error(`希望刪除的屬性不存在`);
          }
        }
      }
      
      // 創建單例對象,全局共享一個數據池
      const store = new Store();
      
      // 創建代理, 私有化 _data, 簡化用戶操作, 提高安全性
      let proxyStore = new Proxy(store, {
        // 若訪問的屬性為 add remove 函數, 直接返回函數
        get: function(store, property) {
          if (property in store) {
            return store[property];
          } else {
            // 若訪問的數據為頁面數據, 則返回頁面代理對象
            if (property in store._data) {
              return store._data[property];
            } else {
              // 若沒有頁面信息, 報錯
              console.error("訪問的頁面數據未載入數據池");
            }
          }
        }
      });
      
      export default proxyStore;


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