EventBus
EventBus (事件总线)是一种组件通信方法,基于发布/订阅模式,能够实现业务代码解耦,提高开发效率
发布/订阅模式
发布/订阅模式是一种设计模式,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新,它包含发布者、订阅者、中介者,消息发布者将消息发送到中介者,然后中介者将消息传递给所有订阅者,而订阅者可以选择接收自己感兴趣的消息
EventBus 的使用
- 初始化
初始化的方法有两个:
- 创建新的 js 文件如 event-bus.js(下例使用该方法)
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
- 在原有的 main.js 中引入
// main.js
Vue.prototype.$EventBus = new Vue()
- 举个简单的例子, 在发布者组件 myButton 组件中,需要在点击事件中通过 EventBus.$emit(‘事件名’,参数),发送事件
<template>
<button @click="decrease()">-</button>
</template>
<script setup>
import { ref } from 'vue';
import EventBus from '../EventBus'
const num=ref(1)
function decrease(){
EventBus.$emit('decrease',num) // 点击按钮发送事件
}
</script>
- 在订阅者组件中,我们需要通过 EventBus.$on(‘事件名’,函数),接收事件
<template>
<div>
<p>{{ count }}</p>
<myButton></myButton>
</div>
</template>
<script>
import myButton from "./components/myButton.vue";
import { EventBus } from './event-bus.js'
export default {
components: {
myButton,
},
data() {
return {
count: 20,
};
},
mounted() {
EventBus.$on("decrease", (num) => {
this.count -= num; // 接收事件进行处理
});
},
};
</script>
效果
点击减号按钮,数字会减一
销毁
有监听事件的组件被销毁时,我们需要取消事件监听,避免潜在的内存泄漏,可以通过 EventBus.$off(‘decrease’,{}) 移除对特定事件的监听,也可以通过 EventBus.$off() 移除所有事件的监听,
优缺点
优点:
- 事件总线可以使组件之间解耦,避免相互依赖,提高可维护性
- 可以方便地实现非父子组件之间的通信
缺点:
- 全局性的事件监听在复杂场景下会导致调试困难
- 注册的事件需要及时清理掉,否则会占用大量内存
- 数据流混乱,通常我们用的是单向数据流,使用事件总线我们很难判断数据在传递过程中哪里出现了问题