当前位置: 代码迷 >> 综合 >> eventbus-免手动解绑方案
  详细解决方案

eventbus-免手动解绑方案

热度:36   发布时间:2023-12-23 05:03:09.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// 获取当前组件实例的uidconst 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(',') : typeEventStore[uid][key] = handlerBus.$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),为了调用当前实例的destroyedthis.bus(this).$on('clearFile', () => {
    // 业务逻辑})// 提交this.bus.$emit('clearFile', true)},

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

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

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