跳到主内容

vue3如何使用EventBus

· 3分钟阅读

我们都知道,在 vue 中,使用 eventBus 是组件通信的一种方式。本文不讨论 eventBus 的原理,来讲解 vue3 中如何优雅使用 eventBus。

vue2 中使用 eventBus

先来回顾 vue2 中如何使用 eventBus。首先导出一个全局的 bus(vue 实例)

export const bus = new Vue();

接下来在需要的位置引入这个实例即可进行监听和发布。

bus.$on(...)
bus.$emit(...)

vue3 中使用 eventBus

在 Vue3 中,Vue 不是一个构造函数,所以我们无法 new 一个实例出来用监听和发布事件了。

幸运的是,官方提供我们可以使用 mitt 第三方库来进行组件间的事件分发。

举个最常见的例子,后台管理系统顶部栏有一个操作菜单开关按钮。

image

接下来我们来使用 mitt 实现这个功能,我们先安装它

npm i --save mitt

main.js 文件里挂载 mitt 实例到 globalProperties 上。

vue 提供了全局配置属性文档,点击 app.config.globalProperties 查看详情

import { createApp } from "vue";
import App from "./App.vue";
import mitt from "mitt";
const emitter = mitt();
const app = createApp(App);
app.config.globalProperties.emitter = emitter;
app.mount("#app");

在左侧菜单,我们通过 emitter 监听事件

<template>
<aside class="sidebar" :class="{'sidebar--toggled': !isOpen}">....</aside>
</template>
<script>
export default {
name: "sidebar",
data() {
return {
isOpen: true,
};
},
mounted() {
this.emitter.on("toggle-sidebar", (isOpen) => {
this.isOpen = isOpen;
});
},
};
</script>

我们在头部的组件按钮的点击事件回调函数中,emit 一个事件即可

<template>
<header>
<button @click="toggleSidebar"/>toggle</button>
</header>
</template>
<script >
export default {
data() {
return {
sidebarOpen: true
};
},
methods: {
toggleSidebar() {
this.sidebarOpen = !this.sidebarOpen;
this.emitter.emit("toggle-sidebar", this.sidebarOpen);
}
}
};
</script>

composition api

我们也可以创建成 composition api,创建文件 src/composables/useEmitter.js

import { getCurrentInstance } from "vue";

export default function useEmitter() {
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;
return emitter;
}

然后就可以这样使用了

import useEmitter from '@/composables/useEmitter'
export default {
setup() {
const emitter = useEmitter()
...
}
...
}