EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的灾难,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。 在本地创建目录vue-bus,在其文件下创建vue-bus.js文件。vue-router 和 Vuex 一样,给Vue添加一个属性bus,并代理emit, on,off三个方法。
vue3.x实现兄弟组件的传值eventBus -- mitt用法
在src下创建一个eventBus.js文件
import Vue from 'vue'
//存储所有的事件
const EventStore = {}
const Bus = new Vue()
const destroyHandler = function () {
// this 为调用此方法的vue组件
// eslint-disable-next-line no-invalid-this
const currentEventobj = EventStore[this._uid]
//如果是动态组件,需要判断是否是属于同一个组件
if (!currentEventobj) {
return
}
//eslint-disable-next-line guard-for-in
for (const type in currentEventobj) {
const key = Array.isArray(type) ? type.join(',') : type
//Bus 解绑事件
Bus.$off(type, currentEventobj[key])
}
//删除记录的事件集合
// eslint disable next-line no-invalid-this
delete Eventstore[this._uid]
}
const EventBus = (vm) => {
//获取当前组件实例的destoryed生命周期
const destroyed = vm.$ptions.destroyed
// 获取当前组件实例的uid
const uid = vm._uid
EventStore[uid] = {}
!destroyed.includes(destroyHandler) && destroyed.push(destroyHandler)
return {
$on: (type, handler) => {
const key = Array.isArray(type) ? type.join('') : type
if (!EventStore?.[uid]?.[key]) {
EventStore[uid][key] = handler
Bus.$on(type, handler)
}
},
$off: (type, handler) => {
if (!type) {
Object.keys(EventStore).forEach((id) => {
delete EventStore[id]
})
Bus.$off()
return
}
const key = Array.isArray(type) ? type.join(',') : type
//删除对应的事事件
delete EventStore[uid][key]
Bus.$off(type, handler)
},
$once: (...params) => Bus.$once(...params),
$emit: (...params) => Bus.$emit(...params),
}
}
// 这两行是允许bus不调用依然能够触发emit和once
EventBus.$emit = (...params) => Bus.$emit(...params)
EventBus.$once = (...params) => Bus.$once(...params)
export default EventBus
兄弟组件1-demo1
import EventBus from '@eventBus.js'
beforeDestroy(){
EventBus(this).$off('cancle_checked')
}
mounted(){
EventBus(this).$on('cancle_checked',(row)=>{
...
})
this.getData()
}
methods:{
getData(){
const {data} = getDataAip()
EventBus(this).$emit('update_fields_data',{data:data})
}
}
兄弟组件2-demo2
beforeDestroy(){
EventBus(this).$off('update_fields_table')
}
mounted(){
// 获取demo1中的update_fields_data数据
EventBus(this).$on('update_fields_data',({data})=>{
this.fieldsData = data
})
// 选中更新table数据
EventBus(this).$on('update_fields_table',({data,checkedKeys,isCheck})=>{
...
})
}
methods:{
handleChange(index){
const checkedItem = this.form[index]
EventBus(this).$emit('cancle_checked',checkedItem)
}
}
需要注意在mounted使用off解除,销毁,因为销毁后,就没必要把监听的句柄存储在bus。
参考文献