Vue全局事件总线(GlobalEventBus)
简介
一种可以在任意组件间通信的方式,本质上就是一个对象,他必须满足以下条件:
1.所有组件对象都必须能看见他。
2.这个对象必须能够使用 $on $emit $off方法去绑定、触发和解绑事件。(因为 $on ,和 $off 和 $emit 这三个方法在Vue原型对象上,所以,我们的全局事件总线就要放在Vue的原型对象(vue.prototype)上,以确保每个组件都能访问得到)
简单理解,全局事件总线其实就是一个中间介质,组件间的相互通信借助于这个中间介质,通过这个中间转换介质,从而完成数据的传递与接收,实现组件间的相互通信。
实现
安装全局事件总线
new Vue({
......
beforeCreate(){
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用,然后就可以使用了
},
......
})
使用事件总线
1.发送(提供)数据方:比如A组件想要接收B组件传递过来的数据,则在B组件中给$bus触发自定义事件。
this.$bus.$emit('xxxx',数据) //xxxx为触发的事件名
2.接收数据方:比如A组件想要接收B组件传递过来的数据,则在A组件中给$bus绑定自定义时间,事件的回调留在A组件自身。
methods:{
receive(data){....}
},
......
mounted(){
this.$bus.$on('xxxx',this.demo) //xxxx为B组件中触发的事件名
//或this.$bus.$on('xxxx',(data)=>{....}) //data为传递过来的数据 注意为箭头函数形式,this的指向才是vm,若是正常函数形式,this指向为undefined
}
解绑事件
最好在beforeDestory钩子中,用$off去解绑当前组件所用到的事件。
完整实例代码
在main.js中
//脚手架已安装vue,不用自己安装vue
import Vue from 'vue'
//引入app组件,它是所有组件的父组件
import App from './App.vue'
// 关闭vue的生产提示
Vue.config.productionTip = false
// 创建vue实例对象——vm
new Vue({
// 将App组件放入容器中
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this //安装全局事件总线
}
}).$mount('#app')
App.vue组件
<template>
<div>
<SchoolMes ref="hw"/>
<Student/>
</div>
</template>
<script>
import SchoolMes from './components/SchoolMes.vue'
import Student from './components/Student.vue';
export default {
name: 'App',
components: {
SchoolMes,
Student
}
</script>
<style>
</style>
Student.vue组件
<template>
<div class="demo">
姓名:{{name}}
<br>
性别:{{sex}}
<br>
<button @click="sendStudentName">发送</button>
</div>
</template>
<script>
export default {
name: 'SchoolMes',
props: {
msg: String
},
data() {
return {
name:'张三',
age:18,
}
},
methods:{
sendStudentName(){
this.$bus.$emit('stuName',this.name)
}
}
}
</script>
<style scoped>
.demo{
background-color: skyblue;
}
</style>
SchoolMes.vue组件
<template>
<div class="demo">
学校:{{ name}}
<br>
地址:{{ address }}
</div>
</template>
<script>
export default {
name: 'SchoolMes',
mounted(){
this.$bus.$on('stuName',(data)=>{
console.log(data)
})
},
// 销毁对应自定义事件
beforeDestroy() {
this.$bus.$off('stuName')
},
data() {
return {
name: 'abcdefghjk',
address: 'beijing',
}
}
}
</script>
<style scoped>
.demo{
background: aquamarine;
}
</style>
消息订阅与发布
1.订阅消息∶消息名
2.发布消息︰消息内容
消息订阅与发布的工作流程:
需要借助第三方库,推荐pubsub-js
使用步骤:
1.安装:npm i pubsub-js
2.引入:import pubsub from ‘pubsub-js’
3.接收数据(订阅者订阅)
mounted() {
// 订阅消息
this.pubsubId = pubsub.subscribe('xxxx',(msgName,data)=>{
console.log(`有人发布了${msgName}消息,消息内容是:${data}`)
})
},
4.提供数据(发布者发布)
sendStudentName() {
// 发布事件
pubsub.publish('xxxx',666)
}
5.取消订阅
beforeDestroy() {
pubsub.unsubscribe(this.pubsubId)
}