1. 程式人生 > >Vue原始碼之createComponent函式(七)

Vue原始碼之createComponent函式(七)

在createElment函式建立vnode時,如果判斷tag標籤是元件的話,會呼叫createComponent函式建立vnode

在createComponent(定義在'src/core/vdom/create-component.js')中,首先是獲得基礎構造器baseCtor。這裡的context是指向vm例項。


在'globalp-api/index.js'中,可以看到option._base指向的是Vue


而在'core/instance/init.js'中,已經將全域性的options與vm例項的options合併,這樣baseCtor指向的就是Vue

然後對元件的構造器Ctor進行擴充套件,實際上執行的是Vue.extend。extend函式在'core/gloabal-api/extend.js'中定義


以下時候Vue的工具方法extend函式。它主要的功能是返回一個元件構造器(函式),擁有Vue相同的功能

首先,Super指向Vue,同時指定一個SuperId,並且定義一個快取構造器cachedCtors用來快取構造器,然後檢查元件的名字是否合法。


然後建立一個sub函式,用來繼承Super(Vue),這裡的繼承使用的是Object.create()函式,該函式的功能是把某個物件(對應這裡的Sub.prototype)的__proto__屬性關聯到指定的物件。


然後對Sub的props和computed做初始化,並擴充套件一些方法和屬性,最後將Sub快取起來,下次如果對應的cachedCtors中有對應的值,就直接返回,不用再建立一個元件的構造器。



回到createComponent函式中,建立Ctor之後判斷是不是函式,不是的話則丟擲警告。然後開始對data進行一些處理。重要的是使用installComponentHooks處理元件的鉤子函式。


在installComponentHooks函式中,先拿到data中的hook,然後迴圈hooksToMerge進行判斷,如果data中存在該hook,則合併,不存在則直接新增到data中。hooksToMerge定義為componentVNodeHooks的keys。componentVNodeHooks的定義如下圖所示。



回到createComponent函式中,在處理完了hooks之後,會建立一個以'vue-component'開頭的vnode

,值得注意的是這個vnode中的children定義的是undefined,而在最後一個引數componentOptions中,傳入了children。然後返回vnode


總結

在建立元件vnode時,主要的步驟是先建立一個元件構造器,這樣可以例項化元件。其中對構造器進行擴充套件,使得具有Vue的功能和方法,然後對data進行一些處理,其中重要的是將元件vnode的hook與data中的hook合併。在處理完之後,新建一個vnode返回。