從$emit 到 父子組件通信 再到 eventBus
阿新 • • 發佈:2018-09-01
win fun prop () undefined cli methods 執行 更新數據
故事還是得從$emit說起,某一天翻文檔的時候看到$emit的說明
觸發當前實例上的事件?就是自身組件上的事件唄,在父子組件通信中,父組件通過props傳遞給子組件數據(高階組件可以用provide和inject),由於這是單向數據流,為了保證復用組件的的時候出現數據錯亂。
那麽只能通過在子組件裏面去觸發一個事件,來讓父組件自己更新數據。
那麽問題來了,$emit不是說好的觸發當前實例上的事件嗎?那是怎麽去能觸發父組件數據更新的呢?難道父組件裏也能$on對應的事件???
其實不是的,看下面這個示例
<div id="app1"> <m-area :v="value" @do="pAdd"></m-area> </div> <script src="js/vue.js"></script> <script> Vue.component(‘mArea‘, { props: [‘v‘], template: ` <div> <button @click="add">{{v}}</button> </div> `, methods: { add() { this.$emit(‘do‘); console.log(this.v) } } }); let app1 = new Vue({ el: ‘#app1‘, data: { value: 1 }, methods: { pAdd() { this.value++; }, mouseover() { console.log(this.value); } } }); </script>
其實Button 的add方法是只觸發了它自身的do事件,但是
<div id="app1">
<m-area :v="value" @do="pAdd"></m-area>
</div>
mArea標簽就是該組件啊,do事件是只觸發了自身的事件,但是m-area標簽是暴露在父組件裏的,看看pAdd方法,它是父組件的mthods裏的一個方法。由此剛好觸發自身組件事件的時候,又觸發了父組件裏的一個方法,數據可以傳參,最終達到更新父組件數據的目的。
接下來說說eventBus
一般都是創建一個bus.js,然後 export default new Vue()
其實背後就是個原理,通過bus.$emit然後涉及到原型鏈查找,相當於直接是針對於根組件App執行的$emit和$on,站在一個上帝視角,最頂層的組件上,就能形成一個事件總線,這樣不同的兄弟組件之間就能進行通信了。
順便可以看看vue-bus這個插件的源碼,其實也是這麽實現的,然後是通過更改get,改了一下調用屬性方法的別名而已,然後掛到vue.prototype上,方便全局調用。
/** * vue-bus v1.1.0 * https://github.com/yangmingshan/vue-bus * @license MIT */ (function (global, factory) { typeof exports === ‘object‘ && typeof module !== ‘undefined‘ ? module.exports = factory() : typeof define === ‘function‘ && define.amd ? define(factory) : (global.VueBus = factory()); }(this, (function () { ‘use strict‘; function VueBus(Vue) { var bus = new Vue(); Object.defineProperties(bus, { on: { get: function get() { return this.$on } }, once: { get: function get() { return this.$once } }, off: { get: function get() { return this.$off } }, emit: { get: function get() { return this.$emit } } }); Vue.bus = bus; Object.defineProperty(Vue.prototype, ‘$bus‘, { get: function get() { return bus } }); } if (typeof window !== ‘undefined‘ && window.Vue) { window.Vue.use(VueBus); } return VueBus; })));
從$emit 到 父子組件通信 再到 eventBus