摘要:上一篇文章中說(shuō)道,函數(shù)要分兩種情況進(jìn)行說(shuō)明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過(guò)了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類(lèi)。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。
上一篇文章中說(shuō)道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說(shuō)明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過(guò)了,今天這篇文章主要介紹第二種情況,Ctor是Vue.extend創(chuàng)建的"子類(lèi)"。
Ctor是Vue.extend創(chuàng)建的"子類(lèi)"Vue.extend方法我們之后的博文再進(jìn)行詳細(xì)介紹,這里大家可以先把Vue.extend的功能籠統(tǒng)的理解為繼承。我們接下來(lái)看resolveConstructorOptions相關(guān)的代碼,如果Ctor是Vue.extend創(chuàng)建的"子類(lèi)",那么在extend的過(guò)程中,Ctor上就會(huì)有super屬性。
Vue.extend = function (extendOptions: Object): Function { ... Sub["super"] = Super ... }
Ctor上有了super屬性,就會(huì)去執(zhí)行if塊內(nèi)的代碼
... const superOptions = resolveConstructorOptions(Ctor.super) const cachedSuperOptions = Ctor.superOptions ... // Vue.extend相關(guān)代碼 Vue.extend = function (extendOptions: Object): Function { ... Sub.superOptions = Super.options // Sub.superOptions指向基礎(chǔ)構(gòu)造器的options ... }
首先遞歸調(diào)用resolveConstructorOptions方法,返回"父類(lèi)"上的options并賦值給superOptions變量。然后把"自身"的options賦值給cachedSuperOptions變量。
然后比較這兩個(gè)變量的值,當(dāng)這兩個(gè)變量值不等時(shí),說(shuō)明"父類(lèi)"的options改變過(guò)了。例如執(zhí)行了Vue.mixin方法,這時(shí)候就需要把"自身"的superOptions屬性替換成最新的。然后檢查是否"自身"d的options是否發(fā)生變化。resolveModifiedOptions的功能就是這個(gè)。
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) .... }
說(shuō)了這么多,大家可能還是有點(diǎn)陌生,我們直接舉個(gè)例子來(lái)說(shuō)明一下。
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改變了"父類(lèi)"options。源碼中superOptions和cachedSuperOptions就不相等了,大家可以去jsfiddle試試效果。
接下來(lái)看看resolveModifiedOptions都干了哪些事情?
function resolveModifiedOptions (Ctor: Class): ?Object { let modified // 定義modified變量 const latest = Ctor.options // 自身的options const extended = Ctor.extendOptions // 構(gòu)造"自身"時(shí)傳入的options const sealed = Ctor.sealedOptions // 執(zhí)行Vue.extend時(shí)封裝的"自身"options,這個(gè)屬性就是方便檢查"自身"的options有沒(méi)有變化 // 遍歷當(dāng)前構(gòu)造器上的options屬性,如果在"自身"封裝的options里沒(méi)有,則證明是新添加的。執(zhí)行if內(nèi)的語(yǔ)句。調(diào)用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 } }
從作者的注釋可以看到這個(gè)方法主要就是防止生命周期構(gòu)造函數(shù)重復(fù)。我們?cè)賮?lái)看該方法傳入的3個(gè)參數(shù)。latest,extended,sealed,lateset表示的是"自身"新增的options。extended表示的是當(dāng)前構(gòu)造器上新增的extended options,sealed表示的是當(dāng)前構(gòu)造器上新增的封裝options。
回到源碼,如果latest不是數(shù)組的話(lateset是"自身"新增的options),這里不需要去重,直接返回latest。如果傳入的latest是數(shù)組(如果latest是數(shù)組,一般這個(gè)新增的options就是生命周期鉤子函數(shù)),則遍歷該數(shù)組,如果該數(shù)組的某項(xiàng)在extended數(shù)組中有或者在sealed數(shù)組中沒(méi)有,則推送到返回?cái)?shù)組中從而實(shí)現(xiàn)去重。(這個(gè)去重邏輯目前自己還不是特別明白,之后如果明白了會(huì)在這里更新,有明白的同學(xué)們請(qǐng)?jiān)谠u(píng)論區(qū)留言)
現(xiàn)在我們了解了resolveModifiedOptions和dedupe方法的作用,接下來(lái)回到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屬性上。調(diào)用mergeOptions方法合并"父類(lèi)"構(gòu)造器上的options和”自身“上的extendOptions(mergeOptions在下一篇博文中介紹),最后返回合并后的options。
看到這里,可能會(huì)感覺(jué)到頭暈,為了讓大家更好的理解。我們來(lái)看下面的流程圖。
下篇博客我們主要講mergeOptions方法,在整個(gè)Vue中屬于比較核心的一個(gè)方法。敬請(qǐng)期待!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107677.html
摘要:上一篇文章中說(shuō)道,函數(shù)要分兩種情況進(jìn)行說(shuō)明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過(guò)了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類(lèi)。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。 上一篇文章中說(shuō)道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說(shuō)明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個(gè)已經(jīng)向大家介紹過(guò)了,今天這篇文章主要介紹第二種情況...
摘要:上篇文章介紹了構(gòu)造函數(shù)的部分實(shí)現(xiàn),當(dāng)前實(shí)例不是組件時(shí),會(huì)執(zhí)行方法。這個(gè)文件就是對(duì)構(gòu)造函數(shù)進(jìn)行的第一層包裝了。但是注意這里的代碼我們構(gòu)造函數(shù)的第二層包裝,就在這個(gè)文件里了。回到的源碼中,當(dāng)不存在時(shí),直接返回基礎(chǔ)構(gòu)造器的。 上篇文章介紹了Vue構(gòu)造函數(shù)的部分實(shí)現(xiàn),當(dāng)前Vue實(shí)例不是組件時(shí),會(huì)執(zhí)行mergeOptions方法。 vm.$options = mergeOptions( re...
摘要:果然我們找到了的構(gòu)造函數(shù)定義。告訴你是一個(gè)構(gòu)造函數(shù),需要用操作符去調(diào)用。在深入方法之前,我們先把目光移到文件里在的構(gòu)造函數(shù)定義之后,有一系列方法會(huì)被立即調(diào)用。下篇博文主要介紹相關(guān)的內(nèi)容,涉及到原型鏈和構(gòu)造函數(shù)以及部分的實(shí)現(xiàn),敬請(qǐng)期待 上篇博文中說(shuō)到了Vue源碼的目錄結(jié)構(gòu)是什么樣的,每個(gè)目錄的作用我們應(yīng)該也有所了解。我們知道core/instance目錄主要是用來(lái)實(shí)例化Vue對(duì)象,所以我...
摘要:在解析完其構(gòu)造函數(shù)上的之后,需要把構(gòu)造函數(shù)上的和實(shí)例化時(shí)傳入的進(jìn)行合并操作并生成一個(gè)新的。檢查組件名稱是否合法首先看傳入的三個(gè)參數(shù),,這三個(gè)參數(shù)分別代表的是該實(shí)例構(gòu)造函數(shù)上的實(shí)例化時(shí)傳入的實(shí)例本身。 前幾篇文章中我們講到了resolveConstructorOptions,它的主要功能是解析當(dāng)前實(shí)例構(gòu)造函數(shù)上的options,不太明白的同學(xué)們可以看本系列的前幾篇文章。在解析完其構(gòu)造函數(shù)...
摘要:閱讀的源碼,或者說(shuō)閱讀一個(gè)框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。人人都能懂的源碼系列文章將會(huì)詳細(xì)的介紹源碼的方方面面。 閱讀Vue的源碼,或者說(shuō)閱讀一個(gè)框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。下面我們來(lái)看看Vue源碼的目錄結(jié)構(gòu)。showImg(https://segmentfault.com/img/bV8fLS?w=598&h=654); Vue各目錄簡(jiǎn)介 下圖是Vue各個(gè)...
閱讀 2518·2021-09-24 10:29
閱讀 3799·2021-09-22 15:46
閱讀 2571·2021-09-04 16:41
閱讀 2977·2019-08-30 15:53
閱讀 1258·2019-08-30 14:24
閱讀 3052·2019-08-30 13:19
閱讀 2170·2019-08-29 14:17
閱讀 3520·2019-08-29 12:55