微信小程序-发布订阅-事件总线-页面组件通信

Posted yw00yw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序-发布订阅-事件总线-页面组件通信相关的知识,希望对你有一定的参考价值。

核心代码(看别人的)

eventbus.js

/**
 * new map()
 * clear 从映射中移除所有元素
 * delete 从映射中移除指定的元素
 * forEach 对映射中的每个元素执行指定操作
 * get 返回映射中的指定元素
 * has 如果映射包含指定元素,则返回true
 * set 添加一个新元素到映射
 * toString 返回映射的字符串表示形式
 * valueOf 返回指定对象的原始值
 */

/**
 * 需求:
 * 能满足页面之间的通讯
 * 能满足页面和组件(component)之间的通讯
 * 能满足组件(component)之间的通讯
 * 为了能正确响应到自己想要的事件,需要通过一个key来标识每一个事件
 * 而且不同的页面可以使用相同的key来作为事件标识
 */

/**
 * 原理
 * 系统中所有的订阅的消息通过一个全局的字典(Map)来存储,其中的key是事件标识,每个key对应一个数组(这里用数组而不用单个对象是为了能在不同的页面能用相同的key订阅事件,因为有时候一个页面发布消息需要多个页面响应),数组中每个元素是一个对象,其中target表示订阅消息的发起者,callback表示对应发起者的回调函数。然后发布消息的时候直接通过对应的key来拿到消息队列,然后遍历队列发布消息。
 */

let events = new Map();
/**
 * 消息订阅
 * key:消息标识
 * target:消息发起者,用来区分相同key不同的消息
 * callback:回调函数
 */
function sub(key, target, callback) 
    // 消息对象
    let eobj =  "target": target, "callback": callback ;
    // 先通过key拿到对应的消息队列
    let value = events.get(key);
    // 当前key已存在消息队列,说明是不同页面相同的key的消息订阅
    if (Array.isArray(value)) 
        // 过滤出消息发起者不同的消息,相当于覆盖key和target都一样的消息
        value = value.filter(function (e) 
            return e.target != target;
        );
        // 过滤出的队列重新插入此次订阅的消息
        value.push(eobj);
        events.set(key, value);
     else 
        // 不是队列表示字典中没有包含当前key的消息,直接插入
        events.set(key, [eobj]);
    
    console.log("funciton sub", events);

/**
 * 消息发布
 * key:消息标识
 * data:回调数据
 */
function pub(key, data) 
    // 通过key拿到消息队列
    let value = events.get(key);
    console.log("pub --- value", value);
    // 如果队列存在则遍历队列,然后调用消息发起者的回调函数,并将data数据进行回调
    if (Array.isArray(value)) 
        value.map(function (e) 
            let target = e.target;
            let callback = e.callback;
            callback.call(target, data);
        );
    

/**
 * 取消订阅
 * key:消息标识
 * target:消息发起者,用来区分相同key不同的消息
 */
function cancel(key, target) 
    const haskey = events.has(key);
    // 是否存在此消息队列
    if (haskey) 
        let value = events.get(key);
        if (Array.isArray(value)) 
            // 如果队列中只有一条数据直接删除
            if (value.length === 1) 
                events.delete(key);
             else 
                // 如果队列中存在多条数据则过滤出和当前取消订阅target不同的消息然后重新设置到key的消息队列中
                value = value.filter(function (e) 
                    return e.target != target;
                );
                events.set(key, value);
            
        
    
    console.log("function cancel", events);


if (wx) 
    wx.sub = sub;
    wx.pub = pub;
    wx.cancel = cancel;


module.exports = 
    sub, // 消息订阅
    pub, // 消息发布
    cancel // 取消订阅

App.js

require("./lib/eventbus.js"); // 导入事件总线,全局定义

使用

  • 通过导入导出的方式使用
  • 通过wx实例的方式使用

index.js

// const events = require('../../lib/eventbus.js');
let that;
Page(
	// 订阅
	onLoad() 
	   that = this;
	   // events.sub('home', that, function(content)
	   //   console.log("............", content);
	   // )
	   wx.sub('home', that, function(content)
	     console.log("............", content);
	   );
	,
	onUnload: function () 
	  	event.cancel('home',that)
	
)

new.js

// const events = require('../../lib/eventbus.js');
let that;
Page(
  // 订阅
  onLoad: function() 
    that = this;
    // events.sub("home", this, function(data) 
    //   console.log("新闻页面", data);
    // );
    wx.sub('home', that, function(content)
      console.log("............", content);
    );
  ,
  // 发布
  hanldeTap() 
    // events.pub("home", [name: "张三"]);
    wx.pub("home", [name: "张三"]);
    wx.navigateBack(
      detla: -1
    )
  ,
  // 取消
  onUnload: function() 
    wx.cancel("home", that);
  
)

以上是关于微信小程序-发布订阅-事件总线-页面组件通信的主要内容,如果未能解决你的问题,请参考以下文章

Vue父子组件间通信(数据传递)

微信小程序 组件间通信与事件

Vue组件间通信 全局事件总线订阅与发布

微信小程序webSocket多人通信案例

vue的全局事件总线

微信小程序学习总结