Vue通过全局事件总线进行任意组件间通信

126 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

前言

组件间通信方式除了父->子:props、子->父:emitsref/emits和ref / refs及Vuex等等方式之外,还有一种方式全局事件总线,也叫GlobalEventBus能够实现任意组件间的通信。本文就来讲解一下如何去实现它。

原理

一个重要的内置关系:VueComponent.prototype.proto === Vue.prototype

首先我们先明确一个内置关系VueComponent.prototype. proto=Vue.prototype,下面用图来说明此关系,那么为什么要有这个关系呢?其实就是因为让组件实例对象(VC)可以访问到Vue原型上的属性、方法

内置关系说明.png

实现

既然有了这个关系,那么我们便可以在Vue的原型中添加一个$bus变量来存储共有的需要的值

安装全局事件总线

main.js:

import Vue from 'vue'
import App from './App.vue'


Vue.config.productionTip = false

const vm = new Vue({
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this
    },
}).$mount('#app')

使用事件总线

  1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

    methods(){
      xxx(data){......}
    }
    ......
    mounted() {
      this.$bus.$on('xxxx',this.xxx)
    }
    
  2. 提供数据:this.$bus.$emit('xxxx',数据)

解绑所用到的事件

在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

beforeDestory(){
   this.$bus.off('xxxx')
}

案例说明

我们通过全局事件总线来实现兄弟间的通信

brother1.vue:

 data () {
       return {
           List:[
               {id:1,name:"张三",age:18},
               {id:2,name:"李四",age:23},
               {id:3,name:"王五",age:30},
               {id:4,name:"陆六",age:46},
               {id:5,name:"燕七",age:7}
           ]
       }
   },
   methods: {
       sendPeopleInfo(){
           this.$bus.$emit('peopleInfo',this.List)
       }
   }

brother2.vue:

   data() {
       return {
           pList:[]
       }
   },
   mounted() {
        this.$bus.$on('peopleInfo',(data) => {
            this.pList=data
        })
   },

页面效果:

Vue全局事件总线.gif

总结

这就是有关Vue全局事件总线的全部内容,适用于任意组件中通信,而且比Vuex通信方式更为简单。我们下期再见!