vue源碼學習筆記2(resolveConstructorOptions)

mergeOptions看完之後,回到initMixin來,注意到在mergeOptions函數中的parent參數是一個resolveConstructorOptions函數的返回值,vue

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是個什麼東西呢,找找資料:segmentfault

Ctor.super是經過Vue.extend構造子類的時候。Vue.extend方法會爲Ctor添加一個super屬性,指向其父類構造器函數

以上來源:https://segmentfault.com/a/1190000014587126this

這時候仍是去看看extend 函數把:spa

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=父級組件的optionsprototype

那resolveConstructorOptions函數的目的也就比較好理解了:主要是解構獲取構造器的options(函數名也能看出來),主要是其中有對於若是構造器也是extend添加的時候應該怎麼處理,以及它們的構造器若是有更新擴展,須要及時更新到下級。code

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
}複製代碼
相關文章
相關標籤/搜索