0
点赞
收藏
分享

微信扫一扫

Vue3 使用 Event Bus

若如初梘 2022-07-27 阅读 93

本文已整理到 Github,地址 👉 ​​blog​​。


我希望我的内容可以帮助你。现在我专注于前端领域,但我也将分享我在有限的时间内看到和感受到的东西。

在 Vue2 中,创建 Event Bus 如下:

export const bus = new Vue()

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

在 Vue3 中,Vue 不再是构造函数,而是 ​​Vue.createApp({})​​​ 返回一个没有 ​​$on​​​、​​$emit​​​ 和 ​​$once​​ 方法的对象。

根据官方文档 ​​Vue 3 迁移指南​​​所建议的,我们可以使用 ​​mitt​​​ 或 ​​tiny-emitter​​ 库在组件之间调度事件。

这里我们使用 mitt,它的源码也很简单,👉 ​​地址​​。

安装

pnpm i mitt

您也可以单独把代码拷贝一份到项目,代码量较少。

用法

与 Vue2 一样,封装为 ​​myBus.js​​:

import mitt from 'mitt'
export default mitt()

或者,你也可以定义为全局变量:

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'

const app = createApp(App)
app.config.globalProperties.emitter = mitt()

然后,封装一个 hooks:

// src/hooks/useEmitter.js
import { getCurrentInstance } from 'vue'

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

return emitter
}

当然,为了方便管理,你也可以在需要用到的地方单独引入 mitt。

示例

假设我们有一个 ​​sidebar​​​ 和 ​​header​​,其中包含一个关闭/打开侧栏的按钮,我们需要该按钮来切换侧边栏组件内的某些属性。

点击按钮发出 ​​toggle-sidebar​​ 带有一些 payload 的事件:

<template>
<button @click="toggleSidebar">toggle</button>
</template>
<script setup>
import { ref } from 'vue'
import useEmitter from '@/hooks/useEmitter'

const sidebarOpen = ref(true)
const emitter = useEmitter()

const toggleSidebar = () => {
sidebarOpen.value = !sidebarOpen.value
emitter.emit('toggle-sidebar', sidebarOpen.value)
}
</script>

在侧边栏中接收带有 payload 的事件:

<template>
<aside class="sidebar" :class="{'sidebar--toggled': !isOpen}">
{{ isOpen }}
</aside>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import useEmitter from '@/hooks/useEmitter'

const isOpen = ref(true)
const emitter = useEmitter()

onMounted(() => {
emitter.on('toggle-sidebar', (isOpen) => {
isOpen.value = isOpen
})
})
</script>

更多资料

​​实现一个 Event Bus​​

举报

相关推荐

0 条评论