在 Vue 3 中,EventBus 的概念仍然存在,但实现方式与 Vue 2 有所不同。Vue 3 移除了 Vue 2 中的 $on、$off 和 $once 方法,因此无法直接通过 Vue 实例创建 EventBus。不过,Vue 3 推荐使用第三方库(如 mitt 或 tiny-emitter)来实现类似的功能。
1. Vue 3 中 EventBus 的变化
Vue 2 的 EventBus
在 Vue 2 中,EventBus 是通过创建一个全局 Vue 实例来实现的:
javascript
复制
// Vue 2 的 EventBus
import Vue from 'vue';
export const EventBus = new Vue();
然后通过 $emit 发送事件,$on 监听事件:
javascript
复制
// 发送事件
EventBus.$emit('custom-event', data);
// 监听事件
EventBus.$on('custom-event', (data) => {
console.log(data);
});
Vue 3 的变化
Vue 3 移除了 $on、$off 和 $once 方法,因此无法直接使用 Vue 实例创建 EventBus。官方推荐使用以下替代方案:
- 使用第三方库(如 mitt 或 tiny-emitter)。
- 使用 Vue 3 的其他通信方式(如
props、emits、provide/inject、Vuex或Pinia)。
2. 使用 mitt 实现 EventBus
mitt 是一个轻量级的事件总线库,非常适合在 Vue 3 中替代 EventBus。以下是使用 mitt 的步骤:
安装 mitt
bash
复制
npm install mitt
# 或者
yarn add mitt
创建 EventBus
在项目中创建一个 bus.ts 文件:
typescript
复制
// src/utils/bus.ts
import mitt from 'mitt';
type Events = {
sendMsg: string;
sendNum: number;
};
const bus = mitt<Events>();
export default bus;
使用 EventBus
发送事件
vue
复制
<template>
<button @click="sendMessage">发送消息</button>
</template>
<script setup>
import bus from '@/utils/bus';
function sendMessage() {
bus.emit('sendMsg', 'Hello from ComponentA');
}
</script>
监听事件
vue
复制
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import bus from '@/utils/bus';
const message = ref('');
onMounted(() => {
bus.on('sendMsg', (data) => {
message.value = data;
});
});
onUnmounted(() => {
bus.off('sendMsg');
});
</script>
mitt 的优势
- 轻量级:压缩后仅 200 字节。
- 简单易用:API 简洁,支持 TypeScript。
- 高性能:基于闭包实现,无
this绑定问题。
3. 其他替代方案
1. 使用 provide/inject
provide/inject 是 Vue 3 推荐的父子组件通信方式,适合在组件树中传递数据:
javascript
复制
// 父组件
import { provide } from 'vue';
provide('message', 'Hello from Parent');
// 子组件
import { inject } from 'vue';
const message = inject('message');
2. 使用 Vuex 或 Pinia
对于复杂的状态管理,推荐使用 Vuex 或 Pinia。它们提供了更强大的状态管理能力,适合大型项目。
3. 使用 props 和 emits
对于父子组件通信,props 和 emits 是最直接的方式:
vue
复制
<!-- 父组件 -->
<ChildComponent :message="message" @update="handleUpdate" />
<!-- 子组件 -->
<script setup>
const props = defineProps(['message']);
const emit = defineEmits(['update']);
function updateMessage() {
emit('update', 'New Message');
}
</script>
4. 总结
- Vue 3 中 EventBus 的实现:通过第三方库(如 mitt)实现,替代 Vue 2 的
$on和$emit。 - 推荐使用场景:小型项目或简单组件通信。
- 其他通信方式:
provide/inject、props/emits、Vuex或Pinia更适合复杂场景。
如果需要更详细的代码示例或进一步探讨,可以参考 mitt 官方文档 或 Vue 3 官方文档。