在VUE中创建并使用EventBus

EventBus

以前的时候自己对Vue的了解不够深,总觉得EventBus和vuex是差不多的东西,直到最近全职做了前端才发现自己之前的理解是错的。vuex的场景是跨组件data通讯,EvnetBus是事件通讯,之前子组件调用父组件的父组件需要两层$emit才能实现,兄弟组件之间通讯也是比较难以解决问题,这个时候我们就需要EventBus来帮助我们了
代码
eventBus的设计非常简单,不到50行就可以完成(去掉注释更少了)

export default class EventBus {
    constructor () {
        // 构造函数
        this.callbackMap = {}
    }
    // 添加事件监听
    $on (eventName, callback) {
        // 按名字保存所有的回调函数
        // 1.判断callbackMap是否保存过相同的事件
        if (!this.callbackMap[eventName]) {
            this.callbackMap[eventName] = []// 没有,就设置一个保存的容器
        }
        // 2.将callback放在容器中
        this.callbackMap[eventName].push(callback) // 对应的emit事件 添加到 this.callbackMap 对象中  调用自定义的函数即可获取到参数
    }
    // 触发事件
    $emit (eventName, ...rest) {
        // 按名字调用保存的所有的回调函数
        // 1.按照名字取出所有的回调
        const callbackArr = this.callbackMap[eventName]
        if (!callbackArr) {
            return// 没有监听的回调
        }
        // 2.一个一个调用回调,并且传参
        callbackArr.map(callbackItem => {
            callbackItem(...rest) // 根据参数 传入对应的 emit自定义函数中
        })
    }
    $off (eventName, callback) {
        if (!eventName) {
            // 移除所有事件监听
            this.callbackMap = {}
            return
        }
        if (!callback) this.callbackMap[eventName] = [] // 移除指定事件的所有监听
        if (callback) {
            // 移除指定事件的指定的某一个监听
            // 获得所有的回调
            const callbackArr = this.callbackMap[eventName]
            // 从数组中删除对应的需要移除的事件
            this.callbackMap[eventName] = callbackArr.filter(callbackItem => {
                return callbackItem != callback
            })
        }
    }
}

注册

//  main.js
import $Eventbus from '@/util/eventBus' // 替换为实际上的你的文件地址
// ...
// ...
Vue.prototype.EventBus= new $Eventbus()
new Vue({
    el: '#app',
    router,
    i18n,
    store,
    $env: getUrlEnv(),
    render: (h) => h(App)
 })

使用

// someA.vue
// 在此处注册on事件
mouted(){
    this.EventBus.$on('take',() => {
        // do something      
    })
    this.$once('hook:beforeDestroy', () => {
      this.Eventbus.$off('take')
    })
}

// 然后你在任意组件内调用 this.EventBus.$emit('take')
posted @ 2020-09-18 22:01  Molyp  阅读(368)  评论(0编辑  收藏  举报