eventbus在vue2中实现非常简单,只需要注册一个vue实例,并且挂载在vue的原型对象上面
import Vue from 'vue'
Vue.prototype.$bus = new Vue()
1.发出事件 => $emit
2.监听事件 => $on
3.销毁事件 => $off
eventBus在vue3中使用起来差不多,但是因为Vue3不再提供$on与emit函数,Vue实例不再实现事件接口,需要使用插件或者自己写一个
先说说插件,用的比较多的就是vue3-eventbus 还有mitt,详细用法可以看官网
需要手写也很简单,而且可以通过eventBus理解发布订阅模式,推荐大家试一试
export default class EventBus{
constructor(){
// 一个数组,存放callback的地方,格式为 事件名:回调函数数组
this.events = {}
}
// 发布
emit(eventName, ...data) {
// 通过可选链运算符,跳过判断直接遍历调用
this.events[eventName]?.forEach(callback => {
callback(...data)
})
}
// 订阅
on(eventName, callback) {
// 用一个三元简单判断一下有无注册事件,有则push,无则添加
console.log('eventName', eventName);
this.events[eventName] ?
this.events[eventName].push(callback) :
this.events[eventName] = [callback]
}
// 取消订阅
off(eventName, callback) {
if (this.events[eventName]) {
for(let i of this.events[eventName]) {
if(this.events[eventName][i] === callback) {
delete this.events[eventName][i]
return
}
}
}
}
}
在main.js中引入
import EventBus from './utils/eventBus'
const eventBus = new EventBus()
// 通过注入提供eventBus
app.provide('$bus', eventBus)
在父组件
<script setup>
import { inject } from 'vue';
import EventBusSon from './components/eventBusSon.vue';
const bus = inject('$bus')
const aa = () => {
bus.emit('a', 1)
}
</script>
<template>
<EventBusSon></EventBusSon>
<button @click="aa">123</button>
</template>
在子组件
<script setup>
import { inject } from 'vue';
const bus = inject('$bus')
console.log(bus);
bus.on('a', (val) => {
console.log(val);
})
</script>