// eventBus.js import Vue from 'vue' export const EventBus = new Vue()
// ComponentA.vue
import { EventBus } from './eventBus'
EventBus.$emit('user-login', { userId: 123, name: 'Alice' }) // ComponentB.vue
import { EventBus } from './eventBus'
export default {
created() {
EventBus.$on('user-login', (data) => {
console.log('用户登录:', data)
})
},
// 务必在销毁时移除监听,否则内存泄漏
beforeDestroy() {
EventBus.$off('user-login')
}
} EventBus.$once('user-login', (data) => {
// 触发一次后自动移除
}) | 问题 | 说明 |
| 内存泄漏 | 忘记调用$off时,组件销毁后监听器仍然存在,重复挂载会叠加监听。 |
| 调试困难 | 事件流向不透明,出问题时很难追踪是哪个组件emit了什么。 |
| 命名冲突 | 全局共享命名空间,不同功能模块的事件名可能冲突。 |
| 无类型安全 | 纯字符串事件名,IDE无法提示,拼写错误运行时才发现。 |
| 时序依赖 | 监听方必须在发送方emit之前完成注册,否则错过事件。 |
| 无状态持久化 | 事件触发是一次性的,后来挂载的组件收不到之前的事件。 |
| 维护成本高 | 项目变大后,事件依赖关系不清晰,重构困难。 |
// Vue 3 推荐使用 mitt 或 tiny-emitter
import mitt from 'mitt'
export const emitter = mitt()
// 发送
emitter.emit('user-login', data)
// 监听
emitter.on('user-login', handler)
// 清除
emitter.off('user-login', handler)