Vue原始碼學習之initEvents

2021-09-11 18:53:24 字數 3849 閱讀 3380

vue原始碼學習之initevents

initlifecycle是vue原始碼中core/instance/events.js下的乙個函式,和上節的initliftcycle一樣,該函式也是在beforecreate鉤子之前呼叫,作用是初始化元件中的事件。下面讓我們來進行**分析。

1、initevents

function

initevents

(vm: component)

}

這個函式的功能就是初始化了乙個存放事件的空物件,只存放掛載在該元件上的事件。_hashookevent屬性是表示父元件是否有將鉤子函式繫結到該元件上。如果父元件有繫結事件到該元件上則呼叫updatecomponentlisteners方法,下面看一下該方法的實現。

2、updatecomponentlisteners

function

updatecomponentlisteners

( vm: component,

listeners: object,

oldlisteners:

?object

), add, remove, vm)

target = undefined

}

這個方法沒有什麼內容,主要就是呼叫updatelisteners更新listener,比較重要的就是add和remove兩個引數,這兩個方法是vue中自己實現兩個新增listener、移除listener的方法。

3、add

function

add(event, fn, once)

else

}

可以看到該方法主要依賴的是on和

on和on

和once兩個vue例項上的方法,這兩個方法還有emi

t和

emit和

emit

和off方法都是通過乙個eventsmixin方法掛載到vue原型物件上的,下面讓我們了解一下這兩個方法的實現。

$on

vue.prototype.

$on=

function

(event: string | array

, fn: function)

: component

}else

}return vm

}

$on方法主要就是將事件push到vue例項的_events物件對應事件屬性下。

$once

vue.prototype.

$once

=function

(event: string, fn: function)

: component

on.fn = fn

vm.$on(event, on)

return vm

}

onc

e方法借

助了乙個

中間函式

實現只調

用一次的

功能,在

fn呼叫

之前就通

過once方法借助了乙個中間函式實現只呼叫一次的功能,在fn呼叫之前就通過

once方法

借助了一

個中間函

數實現只

呼叫一次

的功能,

在fn調

用之前就

通過off方法解除安裝,再執行我們要執行的函式,這樣就只呼叫一次了

回到剛才的add方法,可以發現add方法就是通過呼叫on和

on和on

和once方法進行新增事件。

4、remove

function

remove

(event, fn)

remove的本質是通過off

方法解除安裝

事件,讓

我們直接

看off方法解除安裝事件,讓我們直接看

off方法卸

載事件,

讓我們直

接看off方法。

$off

vue.prototype.

$off

=function

(event?

: string | array

, fn?

: function)

: component

// array of events(event為陣列則乙個乙個刪除)

if(array.

isarray

(event)

)return vm

}// specific event

const cbs = vm._events[event]if(

!cbs)

// 如果只傳入第乙個引數,將該屬性下的所有事件清空if(

!fn)

if(fn)}}

return vm

}

通過**可以看出$off有三種用法,第一種:不傳引數,將所有事件清空;第二種:只傳第乙個引數,將_events物件下的該屬性事件陣列清空;第三種:傳入兩個引數,清除某個特定事件。

$emit

介紹完了on,

on,on

,once,off

肯定還要

介紹一下

off肯定還要介紹一下

off肯定還

要介紹一

下emit方法,$emit是觸發事件的方法,直接看**吧。

vue.prototype.

$emit

=function

(event: string)

: component

" is emitted in component ` +`

$but the handler is registered for "

$". `

+`note that html attributes are case-insensitive and you cannot use `

+`v-on to listen to camelcase events when using in-dom templates. `

+`you should probably use "

$" instead of "

$".`

)}}let cbs = vm._events[event]

if(cbs)

catch(e

)"`)}

}}return vm

}

忽略前面的一大段關於環境的判斷,可以看出$emit方法就是直接觸發vue例項下的_events物件中的方法。

5、updatelisteners

function

updatelisteners

( on: object,

oldon: object,

add: function,

remove: function,

vm: component)if

(isundef

(cur)

)": got `

+string

(cur)

, vm

)}elseif(

isundef

(old)

)add

(event.name, cur, event.once, event.capture, event.passive, event.params)

}else

if(cur !== old)

}for

(name in oldon)

}}

簡單的說就是往vue例項中新增on物件內事件,移除oldon下的事件。

vue原始碼學習

new vue發生了什麼 此處只針對最簡單基礎的new vue過程,一般專案中採用.vue單檔案元件的形式開發,下面會介紹 對於 runtime compile 版本 初始化乙個 vue 例項的一系列相關環境 watcher,lifecycle,methods等等 compile 將 templat...

Vue原始碼之createElement函式(五)

在render 函式中,最後呼叫的是createelement函式來返回vnode,那麼createelement函式到底完成了什麼功能 1.首先看一下vnode的定義 src core vdom vnode.js vnode被定義為乙個類。2.在createelement中,首先檢測data的型別...

vue原始碼之Array

目錄 響應式具體實現 陣列子集和新增元素的追蹤 array中的問題 object通過setter改變屬性的值,所以我們利用getter時傳送依賴收集,在setter時觸發依賴更新,而且vue將資料轉換成響應式資料是在資料初始化時,對object中之後的屬性新增和刪除操作,無法做到自動更新,而是通過v...