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方法的原理。