Vue中的Bus(总线)实现非父子组件通讯

一、Bus 的实现

Vue2.0提供了Vuex进行非父子组件之间的通讯,但在简单的场景下,能够使用一个空的Vue实例做为中央事件总线。html

实现代码示例:vue

<div id="app">
    <c1></c1>
    <c2></c2>
</div>
var Bus = new Vue();   //为了方便将Bus(空vue)定义在一个组件中,在实际的运用中通常会新建一Bus.js
Vue.component('c1',{   //这里以全局组件为例,一样,单文件组件和局部组件也一样适用
template:'<div>{{msg}}</div>',
  data: () => ({
    msg: 'Hello World!'
  }),
  created() {
    Bus.$on('setMsg', content => {     //监听Vue示例 Bus 的某一个事件
      this.msg = content;
    });
  }
});
Vue.component('c2',{
  template: '<button @click="sendEvent">Say Hi</button>',
  methods: {
    sendEvent() {
      Bus.$emit('setMsg', 'Hi Vue!');  //触发vue示例 bus 的某一个事件,而且将参数做为数据传过去
    }
  }
});
var app= new Vue({
    el:'#app'
})

在实际运用中,通常将Bus抽离出来:webpack

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

组件调用时先引入web

// 组件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,致使不能正常通讯app

1.一、推荐使用Bus的方式

(1)直接将Bus注入到Vue根对象中this

import Vue from 'vue'
const Bus = new Vue()
var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  
})

在子组件中经过this.$root.Bus.$on()、this.$root.Bus.$emit()来调用spa

(2)在一个教程视频中看过,也能够经过将Bus放在vue示例的原型对象中使用prototype

Vue.prototype.bus = new Vue();

每一个组件都是一个Vue示例,因此每一个组件都会有bus属性,在组件中能够经过 this.bus.$emit、this.bus.$on 来调用code

Vue.component('c2',{
  template: '<button @click="sendEvent">Say Hi</button>',
  methods: {
    sendEvent() {
      this.bus.$emit('setMsg', 'Hi Vue!');  
    }
  }
});

 

 

参考:http://www.javashuo.com/article/p-kmxnlwbz-gs.htmlcomponent

相关文章
相关标签/搜索