vue Bus总线
有时候两个组件也需要通信(非父子关系)。当然 Vue2.0 提供了 Vuex,但在简单的场景下,可以使用一个空的 Vue 实例作为中央事件总线。
参考:http://blog.csdn.net/u013034014/article/details/54574989?locationNum=2&fps=1
例子:https://segmentfault.com/q/1010000007491994
<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 => { this.msg = content; });} }); Vue.component('c2',{ template: '<button @click="sendEvent">Say Hi</button>', methods: {sendEvent() { Bus.$emit('setMsg', 'Hi Vue!');} } }); var app= new Vue({ el:'#app' })
在实际运用中,一般将 Bus 抽离出来:
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 上(这里用了插件的写法)
// plugin/index.js import Bus from 'vue'; let install = function (Vue) { ... ... // 设置 eventBus Vue.prototype.bus = new Bus(); ... ... } export default {install};// main.js
import Vue from 'vue';
import plugin from './plugin/index';
... ...Vue.use(plugin);
... ...
组件一中定义
... ... created () { this.bus.$on('updateData', this.getdata);}
组件二中调用
this.bus.$emit('updateData', {loading: false});
注意:注册的总线事件要在组件销毁时卸载,否则会多次挂载,造成触发一次但多个响应的情况
beforeDestroy () { this.bus.$off('updateData', this.getData);}