標籤:

vue.js源碼解讀系列 - Vue的自定義事件機制

vue.js源碼解讀系列 - Vue的自定義事件機制

來自專欄 前端小溪

先看一波使用方式:

vm.$on 有兩個參數,第一個參數可以是字元串也可以是數組,第二個是回調函數

  • 監聽當前實例上的自定義事件。事件可以由vm.$emit觸發。回調函數會接收所有傳入事件觸發函數的額外參數

vm.$on(test, function (msg) { console.log(msg)})vm.$on([test1,test2], function (msg) { console.log(msg)})

vm.$once 有兩個參數,第一個是時間名稱只能是字元串,第二個是回調函數

  • 監聽一個自定義事件,但是只觸發一次,在第一次觸發之後移除監聽器

vm.$once(testonce, function (msg) { console.log(msg)})

vm.$off 有兩個參數,第一個參數可以是字元串也可以是數組,第二個是回調函數

  • 如果沒有提供參數,則移除所有的事件監聽器;

  • 如果只提供了事件,則移除該事件所有的監聽器;
  • 如果同時提供了事件與回調,則只移除這個回調的監聽器。

vm.$off()vm.$off(test)vm.$off(test1, function (msg) { console.log(msg)})vm.$off([test1,test2], function (msg) { console.log(msg)})

vm.$emit 有兩個參數,第一個參數觸發的事件名,第二參數傳遞的參數

  • 觸發當前實例上的事件。附加參數都會傳給監聽器回調。

vm.$emit(test, 觸發自定義事件)

下面從源碼來看其實現,vue的自定義事件功能實現在 core/instance/events.js中

1、初始化事件,在vm下掛載_events屬性對象,所有添加的自定義事件都會存放其中

2、$on事件的實現

根據以上分析可以看出 vm._events 的結構為:

vm._events={ test:[fn,fn...], test1:[fn,fn...]}

3、$once事件的實現

根據分析得出 $once綁定的事件 vm.events 的結構為:

vm._events={ oncetest:[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) } , ... ]}

4、$off事件的實現

一一的實現了下面的這三點:

  • 如果沒有提供參數,則移除所有的事件監聽器;
  • 如果只提供了事件,則移除該事件所有的監聽器;
  • 如果同時提供了事件與回調,則只移除這個回調的監聽器。

5、$emit事件的實現

白話描述:匹配到json中相關key值的value,這個value先轉換成真正的數組,再循環遍曆數組,傳入給的參數執行數組中的每個函數。

總結:

整個自定義事件就是在vm下掛載一個_events的Object對象,可以理解為一個json,其中json的key值就是自定義事件的名稱,一個key值可能對應著多個自定義事件,因此json中每個key對應的value都是一個數組,每次執行事件監聽都會向數組中push相關的函數,最終通過$emit函數傳入的參數,匹配到json中相應的key,val值,從而使用給定的參數執行數組中的函數。

最終的vm._events可以是這樣的值:

vm._events={ test1:[fn,fn,fn], test2:[fn], oncetest:[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) }, ... ], ...}

vue中自定義事件的主要作用是組件間的通信,因為_events對象最終掛載在Vue的實例上,因此每個組件都能夠訪問到vm._events的值,也能向其中push相關的訂閱函數。

最典型的用法就是vue組件間的組件通信,父組件使用 :foo.sync , 子組件使用 this.$emit(update:foo, option) 進行雙向通信,如果你有看過vue的源碼就會發現實際上,:foo.sync 最終會綁定一個 update:foo 的事件。

<comp :foo.sync="bar"></comp>會被拓展為<comp :foo="bar" @update:foo="val => bar = val"></comp>

推薦閱讀:

窺探React - 源碼分析
基於CentOS6.4環境編譯Spark-2.1.0源碼
express源碼中的對象繼承
如何看待一加違反開源協議不公開 DASH 快充代碼?

TAG:Vuejs | 源碼 |