前端面试准备1-vue3-eventbus

623 阅读2分钟

在 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。官方推荐使用以下替代方案:

  1. 使用第三方库(如 mitt 或 tiny-emitter)。
  2. 使用 Vue 3 的其他通信方式(如 propsemitsprovide/injectVuex 或 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/injectprops/emitsVuex 或 Pinia 更适合复杂场景。

如果需要更详细的代码示例或进一步探讨,可以参考 mitt 官方文档 或 Vue 3 官方文档。