天天看點

vue源碼解析:vue事件方法之$once方法的實作原理

vue中事件方法一共就四個,挂載在vue執行個體上的$once用來監聽某個自定義事件,通常會用到,那麼$once的内部實作原理是什麼呢?下面我們來詳細說下$once:

參數:

  • {string} event

  • {Function} callback

作用:

監聽一個自定義事件,但是隻觸發一次。一旦觸發之後,監聽器就會被移除。

原理:

Vue.prototype.$once = function (event, fn) {
    const vm: Component = this
    function on () {
        vm.$off(event, on)
        fn.apply(vm, arguments)
    }
    on.fn = fn
    vm.$on(event, on)
    return vm
}
           

 我們可以看到$once函數的邏輯其實很簡單,在函數的内部聲明了一個on函數,on函數裡面第一步移除傳入的事件,第二部執行回掉,是以當訂閱$on事件的時候,此時執行的就是on方法,這樣就實作了事件執行一次後直接将事件删除的功能。但是你會發現有一行代碼on.fn = fn,這是什麼操作呢?我們用子函數

on

替換了原本的訂閱事件所對應的回調

fn

,那麼在事件中心

_events

屬性中存儲的該事件名就會變成如下這個樣子:

vm._events = {
    'xxx':[on]
}
           

但是使用者自己卻不知道傳入的

fn

被替換了,當使用者在觸發該事件之前想調用

$off

方法移除該事件時:

vm.$off('xxx',fn)
           

此時就會出現問題,因為在

_events

屬性中的事件名

xxx

對應的回調函數清單中沒有

fn

,那麼就會移除失敗。這就讓使用者費解了,使用者明明給

xxx

事件傳入的回調函數是

fn

,現在反而找不到

fn

導緻事件移除不了了。

是以,為了解決這一問題,我們需要給

on

上綁定一個

fn

屬性,屬性值為使用者傳入的回調

fn

,這樣在使用

$off

移除事件的時候,

$off

内部會判斷如果回調函數清單中某一項的

fn

屬性與

fn

相同時,就可以成功移除事件了。

這就是vue的$once方法的原理。

繼續閱讀