原生微信小程序页面间通讯-eventbus

643 阅读2分钟

业务场景:小比如A页面跳转到B页面,然后在B页面选择之后会退到A页面,要显示B选择的内容。这时候就可以在A页面注册事件,B页面选择回退到A页面的时候,在B页面给A页面发一个事件通知,刷新A页面的数据。

eventbus工具类
let events = new Map()

/**
 * 消息订阅
 * key:消息标识
 * target:消息发起者,用来区分相同key不同的消息
 * callback:回调函数
 */
function register(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])
  }
}

/**
 * 消息发布
 * key:消息标识
 * data:回调数据
 */
function post(key, data) {
  //通过key拿到消息队列
  let value = events.get(key)
  //如果队列存在则遍历队列,然后调用消息发起者的回调函数,并将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 unregister(key, target) {
  let 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)
      }
    }
  }
}

module.exports = {
  register: register,
  post: post,
  unregister: unregister
}

使用方法

  • B页面
     event_bus.post(refreshHome)//发送消息通知A页面
     wx.navigateBack()
  • A页面
    //订阅事件
    event_bus.register(refreshHome, this, (content) => {//接收B页面的通知
      //TODE 数据更新及其页面刷新
      
    })
 // 页面卸载
  onUnload() {
      //取消订阅
    event_bus.unregister(refreshHome, this)
  },