☀️ Vue 全局事件总线
全局事件总线 GlobalEventBus:一种组件间通信的方式,适用于任意组件间通信。(这不是 Vue 中的 API,是利用现有的功能组合)
要实现这个能给任意组件通信的总线中间件,必须要实现两个条件:
- 所有的组件都能看见它。
- 必须要保证它能够调用
$on
、$off
、$emit
。要保证实现前述的第一个条件,可以考虑要使
vc
组件实例原型对象中能够找到。所以可以利用前述的一个重要关系:组件实例原型与 Vue 实例原型的关系。要保证实现第二个条件,利用生命周期
beforeCreate
,在原型中赋值为组件实例对象。一般写为Vue.prototrype.$bus = this
(this
为当前创建的vm
) 。
使用全局事件总线:(在入口文件
main.js
的beforeCreate
)安装全局事件总线:new Vue({ ...... beforeCreate() { Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm }, ...... })
1
2
3
4
5
6
7使用事件总线:
接收数据:A 组件想要接收数据,就在 A 组件中给
$bus
绑定自定义事件,事件的回调留在 A 组件自身(谁绑定事件,回调在谁身上):methods() { demo(data) { ... } }, ... , mounted() { this.$bus.on('xxx', this.demo) // 向全局事件总线绑定自定义事件 xxx }
1
2
3
4
5
6
7提供数据(谁提供数据谁就触发事件):
this.$bus.$emit('xxx', 数据)
1⚠️ 最好在接收完数据之后,在
beforeDestory
中用$off
去解绑当前组件所用到的事件:beforeDestroy() { this.$bus.$off('xxx') },
1
2
3
- 绑定在
$bus
中的自定义事件命名可能会有冲突,所以要注意不要使用已经定义的自定义事件的命名;并且最好不占用这个自定义事件,使用完后就(在绑定处)解绑该自定义事件。- 为什么在
beforeDestory
中销毁?组件不使用后销毁后,有可能在vc
实例中的自定义事件没有被销毁!
🌰 实现全局事件总线例子:
- 首先在入口文件安装全局事件总线。
- 现在在
School
组件中想要接收来自Student
组件的数据,所以在School
组件中绑定自定义事件hello
,并将回调写在School
组件中:(下面使用箭头函数)
mounted() {
this.$bus.$on('hello', (data) => {
console.log('School receiving StudentName: ', data)
})
}
1
2
3
4
5
2
3
4
5
- 在
Student
组件想要提供数据,则在Student
中触发该自定义事件hello
,并且传递数据到参数中。
<button @click="sendStudentName">把学生名给School组件</button>
1
methods: {
sendStudentName() {
this.$bus.$emit('hello', this.name)
}
}
1
2
3
4
5
2
3
4
5
- 在
School
组件接受完数据,解绑该自定义事件:
beforeDestroy() {
this.$bus.$off('hello')
}
1
2
3
2
3
编辑 (opens new window)
📢 上次更新: 2022/09/02, 10:18:16