前言
在 Vue3 中,由于 $on、$off、$emit 等实例方法被移除,官方不再推荐使用传统的 EventBus 模式。
mitt 是一个轻量级的事件发射器库,体积小(约 200 字节)且支持全部事件的监听 / 触发,是 Vue3 中实现 EventBus 的主流方案。
编译环境下使用
安装 mitt
1 2 3
| npm install mitt --save
yarn add mitt
|
创建全局事件总线实例
在 src/utils/eventBus.js 中创建:
运行
1 2 3 4
| import mitt from 'mitt'
const eventBus = mitt() export default eventBus
|
使用事件总线
发送事件(A 组件)
1 2 3 4 5 6 7
| <script setup> import eventBus from '@/utils/eventBus' // 触发事件(可传递参数) const handleClick = () => { eventBus.emit('send-message', 'Hello from A组件') } </script>
|
监听事件(B 组件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script setup> import eventBus from '@/utils/eventBus' import { onMounted, onUnmounted } from 'vue'
onMounted(() => { // 监听事件(回调函数接收参数) eventBus.on('send-message', (msg) => { console.log('收到消息:', msg) // 输出:收到消息:Hello from A组件 }) })
onUnmounted(() => { // 移除事件监听(避免内存泄漏) eventBus.off('send-message') }) </script>
|
监听所有事件
1 2 3
| eventBus.on('*', (type, msg) => { console.log('事件类型:', type, '参数:', msg) })
|
清除所有事件
网页中使用
在一些事件注入的场景中,我们要在非编译的页面中监听事件,就要使用这种方式。
引用
在静态 HTML 页面的 <head> 或 <body> 中,通过 CDN 引入 mitt 库。
1 2
| <script src="https://unpkg.com/mitt@3/dist/mitt.umd.js"></script>
|
引入后,全局会暴露一个 mitt 函数,用于创建事件总线实例。
创建事件总线实例
在脚本中调用 mitt() 创建全局事件总线:
1 2 3 4
| <script> window.eventBus = mitt(); </script>
|
使用事件总线
可以在页面的任何脚本中使用 eventBus 进行事件通信。
例如:
1 2 3 4 5 6 7 8 9 10
| <script> window.eventBus = window.mitt() window.eventBus.on('message', (data) => { console.info('收到消息:', data) })
setTimeout(() => { window.eventBus.emit('message', '你好') }, 2000) </script>
|
完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>静态页面使用 mitt</title> <script src="https://unpkg.com/mitt@3/dist/mitt.umd.js"></script> </head> <body> <button id="btn">触发事件</button> <div id="result"></div>
<script> window.eventBus = mitt();
window.eventBus.on('message', (data) => { document.getElementById('result').textContent = `收到消息:${data}`; });
document.getElementById('btn').addEventListener('click', () => { window.eventBus.emit('message', 'Hello from 按钮点击!'); });
window.eventBus.on('*', (type, data) => { console.log(`事件类型:${type},数据:${data}`); });
const handleRemove = (data) => { console.log('这是一个可移除的监听:', data); }; window.eventBus.on('removeTest', handleRemove); setTimeout(() => { window.eventBus.off('removeTest', handleRemove); console.log('已移除 removeTest 事件的监听'); }, 5000); </script> </body> </html>
|