微信小程序原生开发实现全局通信

524 阅读1分钟

简单实现一个微信原生开发时全局通信的方法

// app.js
App({
  onLaunch() {
  },
  globalData: {
    // 全局通信监听实例
    Watcher: []
  },
  /**
   * 注册监听事件 组件需注意 应在 attached 钩子函数中注册
   * 应配合 $off 一起使用 - 避免页面或组件多次创建时事件被多次注册
   * @param { String } key 监听事件 key - 同一页面/组件 key 不可重复!!!
   * @param { Function } callback 事件回调
   * @param { vm } target 注册页面/组件 vm (this)
   * 例: $on('watcherCallback', event => { console.log('watcherCallback: ', event) }, this)
   */
  $on(key, callback, target) {
    if (typeof key !== 'string' || typeof callback !== 'function' || !target) throw '$on:参数错误'
    this.globalData.Watcher.push({
      key: key,
      handler: [callback],
      uid: target.__wxExparserNodeId__
    })
  },
  /**
   * 用法同 $on
   * 区别:只执行一次 无需使用 $off 取消监听
   */
  $once(key, callback, target) {
    this.globalData.Watcher.push({
      key: key,
      handler: [callback, () => {
        this.$off(key, target)
      }],
      uid: target.__wxExparserNodeId__
    })
  },
  /**
   * 触发通信
   * @param { String } key 监听事件 key - 同一页面/组件 key 不可重复!!!
   * @param { any } value 通信数据
   * 例: $emit('watcherCallback', { value: 18 })
   */
  $emit(key, value = undefined) {
    this.globalData.Watcher.forEach(item => {
      if (item.key === key) {
        item.handler.forEach(son => {
          typeof son === 'function' && son(value)
        })
      }
    })
  },
  /**
   * 关闭监听
   * @param { String } key 监听事件 key - 同一页面/组件 key 不可重复!!!
   * @param { vm } target 注册页面/组件 vm (this)
   * 例: $off('watcherCallback', this)
   */
  $off(key, target) {
    const index = this.globalData.Watcher.findIndex(item => item.key === key && item.uid === target.__wxExparserNodeId__)
    if (index !== -1) this.globalData.Watcher.splice(index, 1)
  }
})