场景:有时候两个组件也需要通信(非父子关系)。当然Vue2.0提供了Vuex,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。

Bus.js

import Vue from 'vue'
const Bus = new Vue()
export default Bus

组件调用时先引入

组件1

import Bus from './Bus'

export default {
    data() {
        return {
            .........
            }
      },
  methods: {
        ....
        Bus.$emit('log', 120)
    },

  }   

组件2

import Bus from './Bus'

export default {
    data() {
        return {
            .........
            }
      },
    mounted () {
       Bus.$on('log', content => { 
          console.log(content)
        });    
    }    
} 

问题:但这种引入方式,经过webpack打包后可能会出现Bus局部作用域的情况,即引用的是两个不同的Bus,导致不能正常通信

解决:

第①种:可以直接将Bus注入到Vue根对象中。

import Vue from 'vue'
const Bus = new Vue()

var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  

})

  然后在子组件中通过this.$root.Bus.$on(),this.$root.Bus.$emit()来调用

 第②种:将bus挂载到vue.prototype上,

import Vue from 'vue';

// 设置eventBus
Vue.prototype.$bus = new Bus();

...  ...

组件一中定义

... ...
mounted () {
    this.$bus.$on('updateData', this.getdata);
}

组件二中调用

this.$bus.$emit('updateData', {loading: false});

注意:注册的总线事件要在组件销毁时卸载,否则会多次挂载,造成触发一次但多个响应的情况

beforeDestroy () {
        this.bus.$off('updateData', this.getData);
    }
Logo

前往低代码交流专区

更多推荐