有時候兩個組件也需要通信(非父子關系)。當然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); }