Vue原始碼學習心得之$emit和$on以及$off的個人理解
阿新 • • 發佈:2020-08-09
在vue中的自定義事件系統,我們可以在每個元件例項上通過
this.$on('eventName', callback);
來監聽當前例項上的事件,其中eventName必須是一個String或者是一個 Array<string>
然後我們可以通過
this.$emit(eventName, args);
來觸發當前例項上的事件
如果需要解綁事件的監聽,可以通過
this.$off(eventName);
注意,$off如果不指定事件名,則表示移除當前元件例項上的所有的事件監聽器,如果傳入了一個事件名則移除這個事件的所有監聽器,如果事件名和callback同時傳入,則只移除這個回撥的監聽器。
那麼這三個方法的底層原始碼是怎麼實現的呢?
首先這三個方法都是通過eventsMixin()進行初始化並且掛載到vue的原型上,
我們可以進入eventsMixin()的原始碼裡看看到底怎麼掛載的
可以看到這幾個事件方法是直接新增到vue的原型上的
接下來先看看$on的原始碼
變數vm拿到的是當前元件例項,在vue中每一個元件都是一個vue的例項,這個沒什麼好說的。然後首先判斷eventName是不是一個數組,前面提到過$on的第一個引數可以是一個Array<string>
如果是一個數組則依次遍歷每個事件名將當前的事件的回撥註冊到事件列表中。
如果不是一個數組就直接向事件列表中添加回調,其中事件列表就是_events這個物件,
this.$on('listenDataModify', callback);
這裡我註冊了一個listenDataModify的事件監聽器,進入原始碼後發現不是一個數組會走else部分裡的程式碼
在當前例項上的_events物件上直接將listenDataModify註冊進來。
this._events['listenDataModify'] = []; // 它的值是一個數組,然後將callback push到這個listenDataModify中
最後將this返回, $on底層實現大致就是這樣。