事件总线 EventBus
Vue官方推荐的组件之间的的通信是使用状态管理工具Vuex;但是当我们项目不大,通信不复杂使得项目中不值得使用Vuex的时候;我们可以使用今天的主角 EventBus;
原理
new Vue()创建一个不包含dom的vue实例对象;由于 Vue 实例实现了一个事件分发接口;你可以在需要通讯的组件中引入此实例,然后利用此实例对象的实例方法 $on,$off,$emit方法来进行通讯。
-
vm.$on( event, callback )监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。 -
vm.$off( [event, callback] )移除自定义事件监听器。-
如果没有提供参数,则移除所有的事件监听器;
-
如果只提供了事件,则移除该事件所有的监听器;
-
如果同时提供了事件与回调,则只移除这个回调的监听器。
-
-
vm.$emit( eventName, […args] )触发当前实例上的事件。附加参数都会传给监听器回调。
全局事件总线
// main.js
1. Vue.prototype.$eventBus = new Vue();
// 或者
2. var eventBus = {
install(Vue, options) {
Vue.prototype.$eventBus = vue;
}
};
Vue.use(eventBus);
使用
// A 组件
methods: {
todo() {
//...
this.$eventBus.$emit('todoSth', params); //params是传递的参数
}
}
// B 组件
created() {
this.$eventBus.$on('todoSth', (params) => { //获取传递的参数并进行操作
//todo something
})
},
// 在组件销毁前 清除事件监听
beforeDestroy () {
this.$eventBus.$off('todoSth');
}
组件内的事件总线
// src/assets/event-bus.js
import Vue from 'vue'
export const eventBus = new Vue();
使用
// A 组件
<script>
import { eventBus } from "@/assets/event-bus.js";
export default {
methods: {
todo() {
//...
eventBus.$emit('todoSth', params); //params是传递的参数
}
}
}
</script>
// B 组件
<script>
import { eventBus } from "@/assets/event-bus.js";
export default {
created() {
eventBus.$on('todoSth', (params) => { //获取传递的参数并进行操作
//todo something
})
},
// 在组件销毁前 清除事件监听
beforeDestroy () {
eventBus.$off('todoSth');
}
}
注意点
- 为什么第一次触发的时候页面B中的on事件没有被触发?
原因:A页面$emit的时候,B页面还没生成导致$on还没触发监听;所以要确保组件A,B组件同时存在; - 每一次的事件触发执行越来越多?
原因:$on事件是不会自动清楚销毁的,需要我们手动来销毁;
参考资料
vue篇之事件总线
中央事件总线传值及遇见的坑
Vue事件总线(EventBus)使用详细介绍