eventbus-免手动解绑方案

11 篇文章 0 订阅
8 篇文章 0 订阅

为什么会写这个包?

  1. 跨层级组件传值,平级组件传值方案众多,五花八门,维护起来很费劲(如eventbus,inject-provider等等)
  2. vuex?redux?注意了,这两个技术产生的应用场景是全局数据管理,而不是用来处理大量业务数据监听,如果坚持用,那么最后随着项目庞大,store也会庞大,维护成本不言而喻。嗯~modules可以分模块维护,但是,依旧不建议,做技术的严谨性还是要有的
  3. eventbus不是可以解决以上问题嘛?没错的,但是会有一个问题,很多同学协作开发过程代码不规范,那就是只监听,不解绑,那就会导致内存泄漏,项目臃肿。

这个包好处?

  1. 除了父子组件意外,所有的数据传递,都可以用这个包,写法统一,辨识度高
  2. 你尽管提交,监听,不用手动解绑,不会因为数据监听造成代码内存泄漏

这个包适用哪些场景?

  1. 所有跨层级,平级组件数据传递都适用,项目越大用起来更舒服

最佳应用

  1. 建议配合mixins全局注入,爱用不用,看你具体情况吧~

成熟度?

  1. 这…
  2. 要不看两眼源码再决定用不用??
  3. 用来还是挺爽的吧,这里做个记录,这个库已经发了我们的生产环境,让时间检测吧
import Vue from 'vue'

// 存储所有的事件
const EventStore = {}
const Bus = new Vue()

// 存放当前组件实例
const destoryHandler = function () {
  // this 为调用此方法的vue组件
  const currentEventObj = EventStore[this._uid]
  if (!currentEventObj) {
    return
  }
  for (const type in currentEventObj) {
    const key = Array.isArray(type) ? type.join(',') : type
    // Bus 解绑事件
    Bus.$off(type, currentEventObj[key])
  }
  // 删除记录的事件集合
  delete EventStore[this._uid]
}

const BusFactory = (vm) => {
  // 获取当前组件实例的destroyed生命周期
  const destroyed = vm.$options.destroyed
  // 获取当前组件实例的uid
  const uid = vm._uid
  // 不存在则声明一个对象,防止每次只存最后一个
  if (!Object.prototype.hasOwnProperty.call(EventStore, uid)) {
    EventStore[uid] = {}
  }
  !destroyed.includes(destoryHandler) && destroyed.push(destoryHandler)
  return {
    $on: (type, handler) => {
      const key = Array.isArray(type) ? type.join(',') : type
      EventStore[uid][key] = handler
      Bus.$on(type, handler)
    },
    $off: (type, handler) => {
      if (!type) {
        delete EventStore[uid]
        Bus.$off()
        return
      }
      const key = Array.isArray(type) ? type.join(',') : type
      // 删除对应的事件
      delete EventStore[uid][key]
      Bus.$off(type, handler)
    },
    $once: (...params) => Bus.$once(...params),
    $emit: (...params) => Bus.$emit(...params)
  }
}

// 这两行是允许bus不调用依然能够触发emit和once
BusFactory.$emit = (...params) => Bus.$emit(...params)
BusFactory.$once = (...params) => Bus.$once(...params)

export default BusFactory


因为我的项目应用地方很多,所以我在全局的mixins文件中使用了

// this.bus
import bus from '../bus'
export default {
  data() {
    return {
      bus: bus
    }
  },
 }

然后我在全局任何地方使用

  mounted() {
    // 监听,注意监听时,必须给我实例(this),为了调用当前实例的destroyed
    this.bus(this).$on('clearFile', () => {
    // 业务逻辑
    })
    // 提交
    this.bus.$emit('clearFile', true)
  },

看看mixins文件我是全局注入的

import globalMixin from './utils/mixins'
// 全局mixins
Vue.mixin(globalMixin)

如有问题,评论区欢迎斧正,以免误导他人,万分感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值