摘要:上篇文章介紹了構(gòu)造函數(shù)的部分實現(xiàn),當(dāng)前實例不是組件時,會執(zhí)行方法。這個文件就是對構(gòu)造函數(shù)進(jìn)行的第一層包裝了。但是注意這里的代碼我們構(gòu)造函數(shù)的第二層包裝,就在這個文件里了?;氐降脑创a中,當(dāng)不存在時,直接返回基礎(chǔ)構(gòu)造器的。
上篇文章介紹了Vue構(gòu)造函數(shù)的部分實現(xiàn),當(dāng)前Vue實例不是組件時,會執(zhí)行mergeOptions方法。
vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options || {}, vm )
mergeOptions方法,我們之后的博文再來做詳細(xì)介紹。今天主要研究resolveConstructorOptions方法,從字面意思來看,這個方法是來解析constructor上的options屬性的。我們來看源碼。
export function resolveConstructorOptions (Ctor: Class) { let options = Ctor.options // 有super屬性,說明Ctor是Vue.extend構(gòu)建的子類 if (Ctor.super) { const superOptions = resolveConstructorOptions(Ctor.super) const cachedSuperOptions = Ctor.superOptions // Vue構(gòu)造函數(shù)上的options,如directives,filters,.... 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) // update base extend options if (modifiedOptions) { extend(Ctor.extendOptions, modifiedOptions) } options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions) if (options.name) { options.components[options.name] = Ctor } } } return options }
這個方法要分成兩種情況來說明,第一種是Ctor是基礎(chǔ)Vue構(gòu)造器的情況,另一種是Ctor是通過Vue.extend方法擴展的情況。
Ctor是基礎(chǔ)Vue構(gòu)造器當(dāng)Ctor(Ctor其實就是構(gòu)造函數(shù))是基礎(chǔ)Vue構(gòu)造器時,比如是通過new關(guān)鍵字新建Vue構(gòu)造函數(shù)的實例
const vm = new Vue({ el: "#app", data: { message: "Hello Chris" } })
這個時候options就是Vue構(gòu)造函數(shù)上的options。如下圖
那么這個options是在哪里定義的呢?在之前的代碼中好像沒有看到options的定義在哪里?此時我們應(yīng)該怎么去找這個options定義的地方呢?
這里教大家一個方法,首先找到package.json,在這里可以找到我們平時用到的一些npm腳本。以npm run dev為例。實際上npm run dev是執(zhí)行了下列的命令
"dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev"
rollup是類似于webpack的打包工具。我們可以看到這條命令指向了一個地址scripts/config,之后還指定了一個Target。找到script/config,發(fā)現(xiàn)這個文件里
有TARGET為web-full-dev的配置。
// Runtime+compiler development build (Browser) "web-full-dev": { entry: resolve("web/entry-runtime-with-compiler.js"), dest: resolve("dist/vue.js"), format: "umd", env: "development", alias: { he: "./entity-decoder" }, banner }
來分析上面的代碼,入口文件的地址在web/entry-runtime-with-compiler.js。這個文件就是對Vue構(gòu)造函數(shù)進(jìn)行的第一層包裝了。由于今天分析的是options相關(guān)的內(nèi)容,而這層包裝里沒有options相關(guān)的內(nèi)容,所以這個文件我們不展開講(之后有文章會詳細(xì)介紹)。但是注意這里的代碼
... import Vue from "./runtime/index" ...
我們Vue構(gòu)造函數(shù)的第二層包裝,就在這個文件里了。忽略其他的代碼,我們來看關(guān)于Vue.options的部分
... import Vue from "core/index" // 第三層包裝 import platformDirectives from "./directives/index" import platformComponents from "./components/index" ... // install platform runtime directives & components extend(Vue.options.directives, platformDirectives) extend(Vue.options.components, platformComponents) ... // platformDirectives相關(guān) // 這里導(dǎo)出Vue全局指令model,show import model from "./model" import show from "./show" export default { model, show } // platformComponents相關(guān) // 這里導(dǎo)出Vue全局組件Transition,TransitionGroup import Transition from "./transition" import TransitionGroup from "./transition-group" export default { Transition, TransitionGroup }
上面的代碼主要是給Vue.options.directives添加model,show屬性,給Vue.options.components添加Transition,TransitionGroup屬性。那么還有filters,_base屬性,以及components中的KeepAlive又是怎么來的呢?
這就要看Vue的第三層包裝里都做了些什么?找到core/index,同樣我們只看Vue.options相關(guān)代碼。
mport Vue from "./instance/index" import { initGlobalAPI } from "./global-api/index" ... initGlobalAPI(Vue) ...
instance/index 就是我們第二篇文章——構(gòu)造函數(shù)定義的那個文件。這個文件我們之前看過,沒有和Vue構(gòu)造函數(shù)options相關(guān)的代碼。那么我們剩下的沒有配置的options一定是在initGlobalAPI上配置了。接來下看看/global-api/index的代碼。
/* @flow */ import { ASSET_TYPES } from "shared/constants" ... export function initGlobalAPI (Vue: GlobalAPI) { ... Vue.options = Object.create(null) ASSET_TYPES.forEach(type => { Vue.options[type + "s"] = Object.create(null) }) Vue.options._base = Vue extend(Vue.options.components, builtInComponents) ... } // shared/constants.js export const ASSET_TYPES = [ "component", "directive", "filter" ] // core/components/index import KeepAlive from "./keep-alive" export default { KeepAlive }
上面這層包裝就把filters,_base和components中的KeepAlive都實現(xiàn)了。通過這三層包裝,Vue構(gòu)造函數(shù)的options對象就生成了,看這些文字可能有點繞,我們直接上圖。
回到resolveConstructorOptions的源碼中,當(dāng)Ctor.super不存在時,直接返回基礎(chǔ)構(gòu)造器的options。即上圖經(jīng)過兩次包裝的options。那么Ctor.super是什么呢?
Ctor.super是通過Vue.extend構(gòu)造子類的時候。Vue.extend方法會為Ctor添加一個super屬性,指向其父類構(gòu)造器
Vue.extend = function (extendOptions: Object): Function { ... Sub["super"] = Super ... }
所以當(dāng)Ctor時基礎(chǔ)構(gòu)造器的時候,resolveConstructorOptions方法返回基礎(chǔ)構(gòu)造器的options。除了Ctor是基礎(chǔ)構(gòu)造器之外,還有一種是Ctor是通過Vue.extend構(gòu)造的子類。這種情況比較復(fù)雜,下一篇文章專門對其進(jìn)行介紹,敬請期待!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/94597.html
摘要:上一篇文章中說道,函數(shù)要分兩種情況進(jìn)行說明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況...
摘要:上一篇文章中說道,函數(shù)要分兩種情況進(jìn)行說明,第一種是為基礎(chǔ)構(gòu)造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況,是創(chuàng)建的子類。表示的是當(dāng)前構(gòu)造器上新增的,表示的是當(dāng)前構(gòu)造器上新增的封裝。 上一篇文章中說道,resolveConstructorOptions函數(shù)要分兩種情況進(jìn)行說明,第一種是Ctor為基礎(chǔ)構(gòu)造器的情況,這個已經(jīng)向大家介紹過了,今天這篇文章主要介紹第二種情況...
摘要:果然我們找到了的構(gòu)造函數(shù)定義。告訴你是一個構(gòu)造函數(shù),需要用操作符去調(diào)用。在深入方法之前,我們先把目光移到文件里在的構(gòu)造函數(shù)定義之后,有一系列方法會被立即調(diào)用。下篇博文主要介紹相關(guān)的內(nèi)容,涉及到原型鏈和構(gòu)造函數(shù)以及部分的實現(xiàn),敬請期待 上篇博文中說到了Vue源碼的目錄結(jié)構(gòu)是什么樣的,每個目錄的作用我們應(yīng)該也有所了解。我們知道core/instance目錄主要是用來實例化Vue對象,所以我...
摘要:在解析完其構(gòu)造函數(shù)上的之后,需要把構(gòu)造函數(shù)上的和實例化時傳入的進(jìn)行合并操作并生成一個新的。檢查組件名稱是否合法首先看傳入的三個參數(shù),,這三個參數(shù)分別代表的是該實例構(gòu)造函數(shù)上的實例化時傳入的實例本身。 前幾篇文章中我們講到了resolveConstructorOptions,它的主要功能是解析當(dāng)前實例構(gòu)造函數(shù)上的options,不太明白的同學(xué)們可以看本系列的前幾篇文章。在解析完其構(gòu)造函數(shù)...
摘要:閱讀的源碼,或者說閱讀一個框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。人人都能懂的源碼系列文章將會詳細(xì)的介紹源碼的方方面面。 閱讀Vue的源碼,或者說閱讀一個框架的源碼,了解它的目錄結(jié)構(gòu)都是很有幫助的。下面我們來看看Vue源碼的目錄結(jié)構(gòu)。showImg(https://segmentfault.com/img/bV8fLS?w=598&h=654); Vue各目錄簡介 下圖是Vue各個...
閱讀 3381·2021-11-22 12:04
閱讀 2770·2019-08-29 13:49
閱讀 534·2019-08-26 13:45
閱讀 2318·2019-08-26 11:56
閱讀 1065·2019-08-26 11:43
閱讀 644·2019-08-26 10:45
閱讀 1326·2019-08-23 16:48
閱讀 2228·2019-08-23 16:07