1.定义
1.一种组件间通信的方式,适用于任何组件间通信
2.事件总线实际上就是定义一个全局变量将其挂载在Vue实例上,在Vue实例中需要在其生命中期中的beforeCreate中将事件总线挂载在Vue实例上,如果在创建实例之间挂载,则此时实例不存在,无法挂载,如果在创建实例之后挂载,此时页面已经渲染完成,挂载已经不生效
3.安装全局事件总线
new Vue({
...
beforeCreate(){
//将事件总线挂载在Vue实例上
Vue.prototype.$bus = this
}
}).$mount('#app')
4.使用事件总线:
1.接收数据:A组件想接收数据,则应该在A组件中给$bus绑定自定义事件,s事件的回调留在A组件本身
mounted(){
this.$bus.$on('getSchoolName',this.getSchoolName)
this.$bus.$on('getStudentName',this.getStudentName)
},
methods:{
getSchoolName(name){
...
},
getStudentName(name){
...
}
}
2.提供数据
this.$bus.$emit('getSchoolName',this.schoolName)
5.最好在beforeDestroy钩子中,用$off解绑当前组件用到的事件.因为事件过多可能会出现事件名被占用的情况。
6.事件总线实际上就是自定义事件的一种使用方式
2.示例
需求:点击按钮,将子组件scholl和student的schoolName和studentName传给父组件App
在school中
<div class="school">
<span>{{schoolName}}</span>
<button @click="sendShoolName">将学校名传给父组件</button>
</div>
export default {
data(){
return{
schoolName:'北京大学'
}
},
methods:{
sendShoolName(){
//将数据传递给事件总线
this.$bus.$emit('getSchoolName',this.schoolName)
}
}
}
在student中
<div class="student">
<span>{{studentName}}</span>
<button @click="sendStudentName">将学生名传给父组件</button>
</div>
export default {
data(){
return{
studentName:'张三'
}
},
methods:{
sendStudentName(){
//将数据传递给事件总线
this.$bus.$emit('getStudentName',this.studentName)
}
}
}
在父组件App中
<div id="app">
<School/>
<!-- 在组件中使用原生的click事件需要加上native修饰符 -->
<Student/>
<span>{{studentName}}</span>
<span>{{schoolName}}</span>
</div>
import School from './components/school.vue'
import Student from './components/student.vue'
export default ({
name:'App',
components:{School,Student},
data(){
return{
studentName:'',
schoolName:''
}
},
mounted(){
//将自定义事件绑定在事件总线上
this.$bus.$on('getSchoolName',this.getSchoolName)
this.$bus.$on('getStudentName',this.getStudentName)
},
methods:{
getSchoolName(name){
console.log('###',name);
this.schoolName = name
},
getStudentName(name){
console.log('###',name);
this.studentName = name
}
}
})
事件总线能完成任何组件之间数据的传递,在以下情况推荐使用:
一个组件传递数据给它的爷爷组件(可以跳过他的父组件,直接传递数据)
但是如果是普通的父子组件间传递数据,仍推荐使用 prop和emit