全局事件总线
全局事件总线一种组件间通信的方式,适用于任意组件间通信
原理:
全局事件总线基于自定义事件,原理为有一个组件X(也可称为消息中间件),它不属于任何一个组件,跟任何组件都没关系,任何两个组件想传信息都需要通过这个组件,譬如组件A向组件B传递信息,首先组件B给组件X绑定自定义事件,这个事件的回调在组件B身上,然后在A组件去触发组件X身上的组件B绑定的自定义事件,把数据传过去,组件B的回调就收到了数据,这样就实现了任意组件的通信。
实现步骤
第一步:首先需要安装全局事件总线,因为所有组件都要看得见这个组件X,一般会在Vue的原型上绑定,一般叫$bus
new Vue({
...
beforeCreate() {
Vue.prototype.$bus = this//安装全局事件总线
}
...
}).$mount('#app')
第二步:接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
第三步:提供数据,组件B提供数据,需触发$bus的自定义事件
this.$bus.$emit('xxxx',数据)
注意:最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
改造TodoList为全局事件总线
我们给Item组件与App组件的交互改成全局事件总线,之前Item用App的数据通过props先传给List组件,List组件再传给Item组件进行使用
第一步:安装全局事件总线
beforeCreate() {
Vue.prototype.$bus = this//安装全局事件总线
}
第二步:提供数据
Item组件修改为:
methods:{
handleCheck(id){
//console.log(id)
//通知App组件将对应的todo对象的done取反
//this.checkTodo(id)
this.$bus.$emit('checkTodo',id)
},
handleDelete(id){
if (confirm('确定删除吗?')) {
//通知App组件将对应的todo对象
//console.log(id)
//this.deleteTodo(id)
this.$bus.$emit('deleteTodo',id)
}
}
}
第三步:接收数据
App组件改为:
mounted() {
this.$bus.$on('checkTodo',this.checkTodo)
this.$bus.$on('deleteTodo',this.deleteTodo)
},
beforeDestroy() {
this.$bus.$off('checkTodo')
this.$bus.$off('deleteTodo')
}
第四步:把props的方式删除
App组件:
<!--<List :todos="todos" :checkTodo="checkTodo" :deleteTodo="deleteTodo"/>-->
<List :todos="todos"/>
List组件:
<!--<Item v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj" :checkTodo="checkTodo" :deleteTodo="deleteTodo"/>-->
<Item v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj"/>
最后注释List组件和Item组件的props配置项即可