组件通信之事件总线
前言
最近一个vue3项目中,涉及到平级组件和是跨越多层嵌套的组件间的事件通信需求,经过查阅选择了事件总线机制来解决,特此记录总结。
一、事件总线是什么?
Vue 事件总线是一种用于在 Vue 应用程序中进行组件间通信的模式。它允许不同组件之间通过一个中央的事件通道来传递消息和数据,而不需要显式地建立父子组件关系或通过 props 传递数据。事件总线可以简化组件间通信的复杂性,尤其是在跨越多层级的组件之间传递数据时特别有用。
二、实现方式
1.使用 Vue 实例作为事件总线
代码如下(示例):
1.创建一个 Vue 实例作为事件总线,并在全局范围内使用:
// eventBus.js
import Vue from 'vue';
// 创建一个独立的 Vue 实例作为事件总线
const eventBus = new Vue();
export default eventBus;
2.在需要通信的组件中,导入事件总线并使用它来发送和接收事件:
// ComponentA.vue
<template>
<div>
<button @click="sendMessage">Send Message</button>
</div>
</template>
<script>
import eventBus from './eventBus';
export default {
methods: {
sendMessage() {
// 发送消息到事件总线
eventBus.$emit('message', 'Hello from Component A');
},
},
};
</script>
// ComponentB.vue
<template>
<div>
<p>{{ receivedMessage }}</p>
</div>
</template>
<script>
import eventBus from './eventBus';
export default {
data() {
return {
receivedMessage: '',
};
},
mounted() {
// 监听事件总线的消息
eventBus.$on('message', (message) => {
this.receivedMessage = message;
});
},
};
</script>
2.使用eventBus
代码如下(示例):
1.在父组件中创建eventBus并通过provide方法提供出去:
// parent.tsx
/** create event bus */
const eventBus = {
listeners: [],
$on(listener) {
this.listeners.push(listener)
},
$emit(...args) {
this.listeners.forEach(listener => {
listener(...args)
});
}
}
/** provide event bus */
provide('eventBus', eventBus)
2.在需要使用的组件中获取并使用:
// type.ts
/** define eventBus's type */
interface EventBus {
$on: Function,
$emit: Function
}
export type {
EventBus
}
// componentA.tsx
const eventBus = inject<EventBus>('eventBus')
/** call clear console event in bro component with event bus */
const clearConsole = () => {
eventBus.$emit('clearConsole')
}
// componentB.tsx
const eventBus = inject<EventBus>('eventBus')
onMounted(() => {
/** listen to clear console event called by bro component */
eventBus.$on((action: string) => {
if('clearConsole' == action) {
clearConsole()
}
})
})
总结
以上就是今天要讲的内容,本文仅仅简单介绍了vue事件总线的使用,它的底层原理和代码实现有兴趣的同学可以去vue源码中钻研学习。