vue 中兄弟组件或者多级组件之间的通讯,是比较麻烦的,这个时候呢,我们就可以使用 EventBus 来实现我们想要的业务,但是面试的时候又经常会被问到,或者让写出 EventBus,所以就来探索一下
一、Vue中如何使用 EventBus?
1. 初始化时全局定义
import Vue from 'vue' // main.js 中 // 第一种定义方式 Vue.prototype.$eventBus = new Vue() // 第二种定义方式 window.eventBus = new Vue();
2. 触发事件
//使用方式一定义时 // params 多个参数 this.$eventBus.$emit('eventName', param1,param2,...) //使用方式二定义时 eventBus.$emit('eventName', param1,param2,...)
3. 监听事件
//使用方式一定义时 this.$eventBus.$on('eventName', (param1,param2,...)=>{ //需要执行 逻辑代码 // params 多个参数 }) //使用方式二定义时 eventBus.$on('eventName', (param1,param2,...)=>{ //需要执行 逻辑代码 })
4. 移除事件
在开发的过程中,我们要及时移除不使用的 eventBus ,原因:
① 为了避免在监听时,事件被反复触发
② 由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听
③ 未及时移除的 eventBus 会导致内存泄漏
//使用方式一定义时 this.$eventBus.$off('eventName'); //使用方式二定义时 eventBus.$off('eventName');
二、EventBus的原理是什么?
废话少说,直接上代码,用 class 来实现我们自己的 EventBus:
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();