摘要:上一篇文章中說道,函數(shù)要分兩種情況進行說明,第一種是為基礎構造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當前構造器上新增的,表示的是當前構造器上新增的封裝。
上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進行說明,第一種是Ctor為基礎構造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,Ctor是Vue.extend創(chuàng)建的"子類"。
Ctor是Vue.extend創(chuàng)建的"子類"Vue.extend方法我們之后的博文再進行詳細介紹,這里大家可以先把Vue.extend的功能籠統(tǒng)的理解為繼承。我們接下來看resolveConstructorOptions相關的代碼,如果Ctor是Vue.extend創(chuàng)建的"子類",那么在extend的過程中,Ctor上就會有super屬性。
Vue.extend = function (extendOptions: Object): Function { ... Sub["super"] = Super ... }
Ctor上有了super屬性,就會去執(zhí)行if塊內的代碼
... const superOptions = resolveConstructorOptions(Ctor.super) const cachedSuperOptions = Ctor.superOptions ... // Vue.extend相關代碼 Vue.extend = function (extendOptions: Object): Function { ... Sub.superOptions = Super.options // Sub.superOptions指向基礎構造器的options ... }
首先遞歸調用resolveConstructorOptions方法,返回"父類"上的options并賦值給superOptions變量。然后把"自身"的options賦值給cachedSuperOptions變量。
然后比較這兩個變量的值,當這兩個變量值不等時,說明"父類"的options改變過了。例如執(zhí)行了Vue.mixin方法,這時候就需要把"自身"的superOptions屬性替換成最新的。然后檢查是否"自身"d的options是否發(fā)生變化。resolveModifiedOptions的功能就是這個。
if (superOptions !== cachedSuperOptions) { // super option changed, // need to resolve new options. Ctor.superOptions = superOptions // check if there are any late-modified/attached options (#4976) const modifiedOptions = resolveModifiedOptions(Ctor) .... }
說了這么多,大家可能還是有點陌生,我們直接舉個例子來說明一下。
var Profile = Vue.extend({ template: "{{firstName}} {{lastName}} aka {{alias}}
" }) Vue.mixin({ data: function () { return { firstName: "Walter", lastName: "White", alias: "Heisenberg" } }}) new Profile().$mount("#example")
由于Vue.mixin改變了"父類"options。源碼中superOptions和cachedSuperOptions就不相等了,大家可以去jsfiddle試試效果。
接下來看看resolveModifiedOptions都干了哪些事情?
function resolveModifiedOptions (Ctor: Class): ?Object { let modified // 定義modified變量 const latest = Ctor.options // 自身的options const extended = Ctor.extendOptions // 構造"自身"時傳入的options const sealed = Ctor.sealedOptions // 執(zhí)行Vue.extend時封裝的"自身"options,這個屬性就是方便檢查"自身"的options有沒有變化 // 遍歷當前構造器上的options屬性,如果在"自身"封裝的options里沒有,則證明是新添加的。執(zhí)行if內的語句。調用dedupe方法,最終返回modified變量(即”自身新添加的options“) for (const key in latest) { if (latest[key] !== sealed[key]) { if (!modified) modified = {} modified[key] = dedupe(latest[key], extended[key], sealed[key]) } } return modified }
那么dedupe方法又干了什么事情呢?
function dedupe (latest, extended, sealed) { // compare latest and sealed to ensure lifecycle hooks won"t be duplicated // between merges if (Array.isArray(latest)) { const res = [] sealed = Array.isArray(sealed) ? sealed : [sealed] extended = Array.isArray(extended) ? extended : [extended] for (let i = 0; i < latest.length; i++) { // push original options and not sealed options to exclude duplicated options if (extended.indexOf(latest[i]) >= 0 || sealed.indexOf(latest[i]) < 0) { res.push(latest[i]) } } return res } else { return latest } }
從作者的注釋可以看到這個方法主要就是防止生命周期構造函數(shù)重復。我們再來看該方法傳入的3個參數(shù)。latest,extended,sealed,lateset表示的是"自身"新增的options。extended表示的是當前構造器上新增的extended options,sealed表示的是當前構造器上新增的封裝options。
回到源碼,如果latest不是數(shù)組的話(lateset是"自身"新增的options),這里不需要去重,直接返回latest。如果傳入的latest是數(shù)組(如果latest是數(shù)組,一般這個新增的options就是生命周期鉤子函數(shù)),則遍歷該數(shù)組,如果該數(shù)組的某項在extended數(shù)組中有或者在sealed數(shù)組中沒有,則推送到返回數(shù)組中從而實現(xiàn)去重。(這個去重邏輯目前自己還不是特別明白,之后如果明白了會在這里更新,有明白的同學們請在評論區(qū)留言)
現(xiàn)在我們了解了resolveModifiedOptions和dedupe方法的作用,接下來回到resolveConstructorOptions源碼。
if (modifiedOptions) { extend(Ctor.extendOptions, modifiedOptions) } options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions) if (options.name) { options.components[options.name] = Ctor }
如果”自身“有新添加的options,則把新添加的options屬性添加到Ctor.extendOptions屬性上。調用mergeOptions方法合并"父類"構造器上的options和”自身“上的extendOptions(mergeOptions在下一篇博文中介紹),最后返回合并后的options。
看到這里,可能會感覺到頭暈,為了讓大家更好的理解。我們來看下面的流程圖。
下篇博客我們主要講mergeOptions方法,在整個Vue中屬于比較核心的一個方法。敬請期待!
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94629.html
摘要:上一篇文章中說道,函數(shù)要分兩種情況進行說明,第一種是為基礎構造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當前構造器上新增的,表示的是當前構造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進行說明,第一種是Ctor為基礎構造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況...
摘要:上篇文章介紹了構造函數(shù)的部分實現(xiàn),當前實例不是組件時,會執(zhí)行方法。這個文件就是對構造函數(shù)進行的第一層包裝了。但是注意這里的代碼我們構造函數(shù)的第二層包裝,就在這個文件里了。回到的源碼中,當不存在時,直接返回基礎構造器的。 上篇文章介紹了Vue構造函數(shù)的部分實現(xiàn),當前Vue實例不是組件時,會執(zhí)行mergeOptions方法。 vm.$options = mergeOptions( re...
摘要:果然我們找到了的構造函數(shù)定義。告訴你是一個構造函數(shù),需要用操作符去調用。在深入方法之前,我們先把目光移到文件里在的構造函數(shù)定義之后,有一系列方法會被立即調用。下篇博文主要介紹相關的內容,涉及到原型鏈和構造函數(shù)以及部分的實現(xiàn),敬請期待 上篇博文中說到了Vue源碼的目錄結構是什么樣的,每個目錄的作用我們應該也有所了解。我們知道core/instance目錄主要是用來實例化Vue對象,所以我...
摘要:在解析完其構造函數(shù)上的之后,需要把構造函數(shù)上的和實例化時傳入的進行合并操作并生成一個新的。檢查組件名稱是否合法首先看傳入的三個參數(shù),,這三個參數(shù)分別代表的是該實例構造函數(shù)上的實例化時傳入的實例本身。 前幾篇文章中我們講到了resolveConstructorOptions,它的主要功能是解析當前實例構造函數(shù)上的options,不太明白的同學們可以看本系列的前幾篇文章。在解析完其構造函數(shù)...
摘要:閱讀的源碼,或者說閱讀一個框架的源碼,了解它的目錄結構都是很有幫助的。人人都能懂的源碼系列文章將會詳細的介紹源碼的方方面面。 閱讀Vue的源碼,或者說閱讀一個框架的源碼,了解它的目錄結構都是很有幫助的。下面我們來看看Vue源碼的目錄結構。showImg(https://segmentfault.com/img/bV8fLS?w=598&h=654); Vue各目錄簡介 下圖是Vue各個...
閱讀 854·2021-11-19 11:29
閱讀 3349·2021-09-26 10:15
閱讀 2855·2021-09-22 10:02
閱讀 2433·2021-09-02 15:15
閱讀 1970·2019-08-30 15:56
閱讀 2408·2019-08-30 15:54
閱讀 2903·2019-08-29 16:59
閱讀 635·2019-08-29 16:20