Skip to content

Vue中 EventBus 的使用,如何实现Vue中的EventBus

vue 中兄弟组件或者多级组件之间的通讯,是比较麻烦的,这个时候呢,我们就可以使用 EventBus 来实现我们想要的业务,但是面试的时候又经常会被问到,或者让写出 EventBus,所以就来探索一下

一、Vue中如何使用 EventBus?

主要是使用vue自带的$on 、$emit 、$off

vue官方文档:vue事件

image-20230819144100432

image-20230819144112399

image-20230819144143159

使用 $emit 触发事件、使用$on 监听事件,所以可以通过 $emit传递数据 $on监听数据,实现组件间数据传递

  1. 初始化时全局定义
js
import Vue from 'vue'

// main.js 中

// 第一种定义方式
Vue.prototype.$eventBus = new Vue()


// 第二种定义方式
window.eventBus = new Vue();
  1. 触发事件
js
//使用方式一定义时
// params 多个参数
this.$eventBus.$emit('eventName', param1,param2,...)


//使用方式二定义时
eventBus.$emit('eventName', param1,param2,...)
  1. 监听事件
js
//使用方式一定义时
this.$eventBus.$on('eventName', (param1,param2,...)=>{
    //需要执行 逻辑代码
    // params 多个参数
})


//使用方式二定义时
eventBus.$on('eventName', (param1,param2,...)=>{
    //需要执行 逻辑代码
})
  1. 移除事件

    在开发的过程中,我们要及时移除不使用的 eventBus ,原因:

① 为了避免在监听时,事件被反复触发

② 由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听

③ 未及时移除的 eventBus 会导致内存泄漏

js
//使用方式一定义时
this.$eventBus.$off('eventName');

//使用方式二定义时
eventBus.$off('eventName');

二、EventBus的原理是什么?

废话少说,直接上代码,用 class 来实现我们自己的 EventBus:

js
class MyEventBus {
    constructor() {
        // 存储所有事件对应的回调的对应关系
        /**
         * key : [ callback, callback ]
         */

        this.items = {};
    }
     
    // 监听
    $on(eventName, callback) {
        if (!this.items[eventName]) {
            //一个事件可能有多个监听者
            this.items[eventName] = [];
        }
        this.items[eventName].push(callback)
     
        // 简化版写法 等同于上面
        // (this.items[eventName] ||= []).push(callback)
    }

    // 触发监听
    $emit(eventName, ...args) {
        if (!this.items[eventName]) return;
        this.items[eventName].forEach(ca => ca(...args))
    }

    // 去掉监听
    $off(eventName) {
        this.items[eventName] = []
    }
}

export default new MyEventBus();

前端知识体系 · wcrane