参考: https://blog.csdn.net/i168wintop/article/details/95107935
问题背景:vue中除父子组件通信外,任意两个组件间的通讯问题。
解决方案:1.使用vuex,共享一个状态,通过修改和监听这个状态实现组件通信。
2.事件总线。
思路:根据vue.js文档,vm.$on、vm.$off都是其实例方法,因此我们需要一个vue实例作为事件总线对象。
使用方式:
第一种:将事件总线对象绑定在应用根示例的data属性上
① 事件总线的绑定
new Vue({ el: "#app", components: { App }, template: "<App/>", data: { eventHub: new Vue() } });
② 事件总线的使用
addDragUploadListener () { document.getElementById('template-upload-list').addEventListener('dragover', (event) => { this.$root.eventHub.$emit('drag-upload-open', event) }) }, addUploadFinishListener () { this.$root.eventHub.$on('upload-progress-finish', () => { this.loadListData() }) }, removeUploadFinishListener () { this.$root.eventHub.$off('upload-progress-finish') },
第二种:将事件总线对象绑定到Vue原型上
① 绑定
// main.js Vue.prototype.$EventBus = new Vue()
或
var EventBus = new Vue(); Object.defineProperties(Vue.prototype, { $bus: { get: function () { return EventBus } }
② 使用
this.$bus.$emit('nameOfEvent', { ... pass some event data ...}); this.$bus.$on('nameOfEvent',($event) => { // ... })
第三种:定义事件总线,只在需要的组件中引入
注意点:此方式引用,需要在组件销毁时移除绑定的监听事件
① 新创建一个 .js 文件,比如 event-bus.js
// event-bus.js import Vue from 'vue' export const EventBus = new Vue()
② 使用
<!-- A.vue --> <template> <button @click="sendMsg()">-</button> </template> <script> import { EventBus } from "../event-bus.js"; export default { methods: { sendMsg() { EventBus.$emit("aMsg", '来自A页面的消息'); } } }; </script>
综上,以上三种方式均可实现需求,个人倾向于前两种。