本文已整理到 Github,地址 ?? blog。
如果我的內(nèi)容幫助到了您,歡迎點(diǎn)個(gè) Star ?????? 鼓勵(lì)鼓勵(lì) :) ~~
我希望我的內(nèi)容可以幫助你?,F(xiàn)在我專注于前端領(lǐng)域,但我也將分享我在有限的時(shí)間內(nèi)看到和感受到的東西。
在 Vue2 中,創(chuàng)建 Event Bus 如下:
export const bus = new Vue()
bus.$on(...)
bus.$emit(...)
在 Vue3 中,Vue 不再是構(gòu)造函數(shù),而是 Vue.createApp({}) 返回一個(gè)沒(méi)有 $on、$emit 和 $once 方法的對(duì)象。
根據(jù)官方文檔 Vue 3 遷移指南所建議的,我們可以使用 mitt 或 tiny-emitter 庫(kù)在組件之間調(diào)度事件。
這里我們使用 mitt,它的源碼也很簡(jiǎn)單,?? 地址。
安裝
pnpm i mitt
您也可以單獨(dú)把代碼拷貝一份到項(xiàng)目,代碼量較少。
用法
與 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()
然后,封裝一個(gè) 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
}
當(dāng)然,為了方便管理,你也可以在需要用到的地方單獨(dú)引入 mitt。
示例
假設(shè)我們有一個(gè) sidebar 和 header,其中包含一個(gè)關(guān)閉/打開(kāi)側(cè)欄的按鈕,我們需要該按鈕來(lái)切換側(cè)邊欄組件內(nèi)的某些屬性。
點(diǎn)擊按鈕發(fā)出 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>
在側(cè)邊欄中接收帶有 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>