自建类型安全的事件总线:用Composable替代全局EventBus的10倍稳妥方案
抛弃传统的new Vue()事件总线,利用Composable + Symbol + provide/inject构建带类型推断的强类型事件系统,支持自动清理。 · 难度:入门 · +10XP
类型安全的事件总线
Vue3推荐使用Composable替代全局混入,但事件总线的替代方案常被忽视。本教程创建一个事件总线Composable:基于Symbol定义事件类型,使用WeakMap管理监听器,自动在组件卸载时移除订阅。支持on/off/emit/once完整接口,且提供TypeScript自动补全,彻底解决事件命名冲突与内存泄漏。
// useEventBus.js
import { onUnmounted } from 'vue'
const listeners = new WeakMap()
export function useEventBus() {
const bus = {
on(event, handler) {
if (!listeners.has(bus)) listeners.set(bus, new Map())
const handlers = listeners.get(bus) || new Map()
if (!handlers.has(event)) handlers.set(event, new Set())
handlers.get(event).add(handler)
},
emit(event, ...args) {
const handlers = listeners.get(bus)?.get(event)
if (handlers) handlers.forEach(fn => fn(...args))
},
off(event, handler) {
listeners.get(bus)?.get(event)?.delete(handler)
}
}
onUnmounted(() => listeners.delete(bus))
return bus
}