mergeOptions看完以後,回到initMixin來,注意到在mergeOptions函式中的parent引數是一個resolveConstructorOptions函式的返回值,
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
//主體
function resolveConstructorOptions (Ctor) {
var options = Ctor.options;
if (Ctor.super) {
var superOptions = resolveConstructorOptions(Ctor.super);
var cachedSuperOptions = Ctor.superOptions;
if (superOptions !== cachedSuperOptions) {
// super option changed,
// need to resolve new options.
Ctor.superOptions = superOptions;
// check if there are any late-modified/attached options (#4976)
var 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
}
複製程式碼
以上是函式主體,先是建立了一個options物件來儲存當前ctor的iotionps,如果該ctor沒有super屬性就直接返回options,那麼這個super是個什麼東西呢,找找資料:
Ctor.super是通過Vue.extend構造子類的時候。Vue.extend方法會為Ctor新增一個super屬性,指向其父類構造器
以上來源:https://segmentfault.com/a/1190000014587126
這時候還是去看看extend 函式把:
Vue.extend = function (extendOptions) {
extendOptions = extendOptions || {};//如果沒有傳入options則賦值為空物件
var Super = this;//指向vue構造器
var SuperId = Super.cid;//vue的id? 啥意思啊
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});//是否已註冊,有沒有父元件,沒有則為空
if (cachedCtors[SuperId]) {//如果有構造器元件,則直接返回構造器元件的id
return cachedCtors[SuperId]
}
var name = extendOptions.name || Super.options.name;//建立name
if ("development" !== 'production' && name) {//跳過先
validateComponentName(name);
}
var Sub = function VueComponent (options) {//建立Sub物件
this._init(options);
};
Sub.prototype = Object.create(Super.prototype);//重新函式指向原型
Sub.prototype.constructor = Sub;//
Sub.cid = cid++;//給sub新增id
Sub.options = mergeOptions(//合併options
Super.options,
extendOptions
);
Sub['super'] = Super;//給sub新增super指向構造器
// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
//對於props和computed屬性,我們在
//擴充套件時擴充套件原型上的Vue例項。這個
//避免為每個建立的例項呼叫object.defineproperty。
if (Sub.options.props) {//在sub的原型上建立_props屬性,並且按照props建立訪問器屬性新增到該屬性上(為什麼不直接放在sub上呢?)
initProps$1(Sub);
}
if (Sub.options.computed) {//建立計算器屬性,具體同上
initComputed$1(Sub);
}
// allow further extension/mixin/plugin usage
Sub.extend = Super.extend;//複製構造器的extent屬性
Sub.mixin = Super.mixin;//複製構造器的mixin屬性
Sub.use = Super.use;//複製構造器的use屬性
// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
Sub[type] = Super[type];//複製構造器其他資源
});
// enable recursive self-lookup
if (name) {
Sub.options.components[name] = Sub;
}
// keep a reference to the super options at extension time.
// later at instantiation we can check if Super's options have
// been updated.
//保持和父元件options的擴充套件性更新,即使extend已經被例項化
Sub.superOptions = Super.options;//父級options
Sub.extendOptions = extendOptions;//自己的options
Sub.sealedOptions = extend({}, Sub.options);//合併的options
// cache constructor
cachedCtors[SuperId] = Sub;//建立superId屬性指向sub構造器
return Sub
};
複製程式碼
整整看了半天,得出:Ctor.superOptions=父級元件的options
那resolveConstructorOptions函式的目的也就比較好理解了:主要是解構獲取構造器的options(函式名也能看出來),主要是其中有對於如果構造器也是extend新增的時候應該怎麼處理,以及它們的構造器如果有更新擴充套件,需要及時更新到下級。
function resolveConstructorOptions (Ctor) {
var options = Ctor.options;
if (Ctor.super) {//是否有父級元件
var superOptions = resolveConstructorOptions(Ctor.super);//遞迴解構父級元件,獲取所有上級的options合集
var cachedSuperOptions = Ctor.superOptions;//父級元件的options
if (superOptions !== cachedSuperOptions) {//如果父級元件被改變過,更新superOptions
// super option changed,
// need to resolve new options.
Ctor.superOptions = superOptions;
// check if there are any late-modified/attached options (#4976)
//檢查是否有任何後期修改/附加選項
var modifiedOptions = resolveModifiedOptions(Ctor);
// update base extend options
//更新擴充套件的options
if (modifiedOptions) {
extend(Ctor.extendOptions, modifiedOptions);
}
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);//合併options
if (options.name) {
options.components[options.name] = Ctor;
}
}
}
return options
}複製程式碼