商城系統(tǒng) 注冊

小程序跨頁傳遞事件消息和數(shù)據(jù)的實(shí)現(xiàn)方式

2020-09-27|HiShop
導(dǎo)讀:由于微信小程序 wx.navigateBack 方法并不支持返回傳值,導(dǎo)致頁面在返回后,不能方便地即時(shí)更新數(shù)據(jù)。那么小程序跨頁傳遞事件消息和數(shù)據(jù)要如何解決呢。...

由于微信小程序 wx.navigateBack 方法并不支持返回傳值,導(dǎo)致頁面在返回后,不能方便地即時(shí)更新數(shù)據(jù)。那么小程序跨頁傳遞事件消息和數(shù)據(jù)要如何解決呢。

 

一.需求分析

此類需求大概意思是:A 頁面進(jìn)入 B 頁面,B 頁面返回并傳值給 A或在B頁面觸發(fā)事件時(shí),A頁面也有事件觸發(fā)改變。

小程序跨頁傳遞事件消息和數(shù)據(jù)的實(shí)現(xiàn)方式

業(yè)務(wù)分析

普遍方法為: 
第一種:利用微信的 wx.setStorage,將數(shù)據(jù)緩存在小程序?qū)嵗齼?nèi)。從 B 頁面返回 A 頁面時(shí),B 頁面先將數(shù)據(jù)緩存;然后在 A 頁面的 onshow 方法里,調(diào)用 wx.getStorage 讀取緩存來實(shí)現(xiàn)。但為日后維護(hù)帶來大量隱患。(用全局變量方法類似)

第二種:獲取前一個(gè) page 實(shí)例的方法,也可以實(shí)現(xiàn)此功能。部分代碼如下:


小程序跨頁傳遞事件消息和數(shù)據(jù)的實(shí)現(xiàn)方式

  1. var pages = getCurrentPages();
  2. var currPage = pages[pages.length - 1]; //當(dāng)前頁面
  3. var prevPage = pages[pages.length - 2]; //上一個(gè)頁面
  4.  
  5. //直接調(diào)用上一個(gè)頁面的 setData() 方法,把數(shù)據(jù)存到上一個(gè)頁面中去
  6. prevPage.setData({
  7. mdata:1
  8. })

這種方法的弊端:因?yàn)檫M(jìn)入 B 頁面的入口可能是很多個(gè)。這樣做,可能會(huì)導(dǎo)致獲取到的頁面實(shí)例不正確。

二.方法介紹

(onfire.js的下載地址https://github.com/hustcc/onfire.js)  下面進(jìn)入正題介紹onfire.js()  onfire.js 是一個(gè)很簡單的事件分發(fā) JavaScript 庫(僅僅 0.9kb),簡潔實(shí)用。它可以應(yīng)用于:  1.簡單的事件分發(fā)。  2.在 React、Vue.js、Angular 中用于跨組件的輕量級實(shí)現(xiàn)。  3.事件訂閱和發(fā)布。

使用思路:(做過移動(dòng)端開發(fā)的都知道,類似于iOS的通知和安卓的廣播)  a.A 頁面先訂閱一個(gè)事件,并定義處理方法;  b.從 B 頁面返回時(shí),發(fā)送消息;  c.A 頁面卸載時(shí),解除訂閱。

我的使用方法為:  A 頁面代碼:


  1. var onfire = require("../utils/onfire.js");
  2. var that;
  3. var eventObj = onfire.on('key', function () {
  4. // 當(dāng)消息被傳遞時(shí),做具體的事
  5. });
  6.  
  7. Page({
  8. data: {
  9. },
  10. onLoad: function(options) {
  11. // Do some initialize when page load.
  12. },
  13. onReady: function() {
  14. // Do something when page ready.
  15. },
  16. onUnload: function (e) {
  17. onfire.un('key');
  18. onfire.un(eventObj);//移除
  19. }
  20. })

我們可以在 A 頁面直接調(diào)用 onfire.on 方法,訂閱一個(gè)名字為 key 的消息。在上面的代碼中,消息附帶的參數(shù)無傳參。  如果需要傳參的話,直接在 function 里增加參數(shù)即可,例如:


  1. var eventObj = onfire.on('key', function (data){
  2. // 執(zhí)行操作
  3. })

需要注意的是,一定要在 onUnload 里(在頁面被關(guān)閉時(shí))取消訂閱消息,并取消綁定 eventObj。

B 頁面里代碼在回調(diào)的地方加入以下代碼:


  1. onfire.fire('key');//key 為上文中訂閱的消息
  2. // 有參數(shù)時(shí)
  3. onfire.fire('key','test');

三.分析庫代碼


  1. function _bind(eventName, callback, is_one, context) {
  2. if (typeof eventName !== string_str || typeof callback !== function_str) {
  3. throw new Error('args: '+string_str+', '+function_str+'');
  4. }
  5. if (! hasOwnKey(__onfireEvents, eventName)) {
  6. __onfireEvents[eventName] = {};
  7. }
  8. __onfireEvents[eventName][++__cnt] = [callback, is_one, context];
  9.  
  10. return [eventName, __cnt];
  11. }

從代碼中可以看出訂閱 on 方法的時(shí)候,實(shí)際調(diào)用 _bind 方法。該方法利用一個(gè)二維數(shù)組,來存儲(chǔ)訂閱的對象。

 

  1. function _fire_func(eventName, args) {
  2. if (hasOwnKey(__onfireEvents, eventName)) {
  3. _each(__onfireEvents[eventName], function(key, item) {
  4. item[0].apply(item[2], args); //執(zhí)行訂閱時(shí)的方法
  5. if (item[1]) delete __onfireEvents[eventName][key]; // 當(dāng)類型為只訂閱一次時(shí),通知后即移除自己。
  6. });
  7. }
  8. }

而 fire 發(fā)送消息方法的實(shí)質(zhì),是調(diào)用 _fire_func 方法,通過名字(key)來遍歷訂閱者,然后通知訂閱者。

 

  1. function un(event) {
  2. var eventName, key, r = false, type = typeof event;
  3. if (type === string_str) {
  4. // 如果存在key值,則移除數(shù)組
  5. if (hasOwnKey(__onfireEvents, event)) {
  6. delete __onfireEvents[event];
  7. return true;
  8. }
  9. return false;
  10. }
  11. else if (type === 'object') {
  12. eventName = event[0];
  13. key = event[1];
  14. //如果找到這個(gè)對象則卸載
  15. if (hasOwnKey(__onfireEvents, eventName) && hasOwnKey(__onfireEvents[eventName], key)) {
  16. delete __onfireEvents[eventName][key];
  17. return true;
  18. }
  19. //否則返回false
  20. return false;
  21. }
  22. else if (type === function_str) {
  23. //兩層循環(huán)來判斷方法名
  24. _each(__onfireEvents, function(key_1, item_1) {
  25. _each(item_1, function(key_2, item_2) {
  26. if (item_2[0] === event) {
  27. delete __onfireEvents[key_1][key_2];
  28. r = true;
  29. }
  30. });
  31. });
  32. return r;
  33. }
  34. return true;
  35. }

調(diào)用un方法,通過名字(key)來遍歷訂閱者,找到后移除。

注:因?yàn)樾遁d支持按 key、對象、方法卸載,所以需要先判斷類型,然后按各自規(guī)則去解除綁定。

HiShop小程序工具提供多類型商城/門店小程序制作,可視化編輯 1秒生成5步上線。通過拖拽、拼接模塊布局小程序商城頁面,所看即所得,只需要美工就能做出精美商城。更多小程序商店請查看:小程序商店  

電話咨詢 預(yù)約演示 0元開店