Vue 子类构造器 — Vue.extend
前些章节,学习了到了
vue
内部提供的四个默认选项'component', 'directive', 'filter', 和 _base
,传递一个选项配置初始化时,所需合并的选项亦是前三个关键的默认选项,而Vue
中做大量的选项合并策略的篇幅和子类构造器
有一定的关联
幕后NPC—子类构造器
根据Vue
官网,可知:
Vue.extend( options )
参数:
{Object} options
用法:
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
data
选项是特例,需要注意 - 在Vue.extend()
中**它必须是函数**
例:创建一个Child
的子类,继承于父类Parent
,将子类挂载到#app
元素上。获取的data
是选项合并后的结果
var Parent = Vue.extend({
data() {
test: '父',
test1: '父1'
}
})
var Child = Parent.extend({
data() {
test: '子',
test2: '子1'
}
})
var vm = new Child().$mount('#app');
console.log(vm.$data);
// result
{
test: '子',
test1: '父1',
test2: '子1'
}
其中,vm.$mount()
的用法:
如果Vue
实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount()
手动地挂载一个未挂载的实例。如果没有提供 elementOrSelector
参数,模板将被渲染为文档之外的的元素,必须使用原生 DOM API
把它插入文档中。该方法返回实例自身,因而可以链式调用其它实例方法。
通过观察Vue.extend
实现方式,:
Vue.extend = function (extendOptions) {
extendOptions = extendOptions || {};
var Super = this;
var SuperId = Super.cid;
// 注意:增加缓存策略,反复调用该方法其实返回同一个结果
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
var name = extendOptions.name || Super.options.name;
if (name) {
// 检验名称是否合乎规范
validateComponentName(name);
}
// 创建子类构造器
var Sub = function VueComponent (options) {
this._init(options);
};
// 子类继承父级
// -- Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。返回一个新对象,带着指定的原型对象和属性
Sub.prototype = Object.create(Super.prototype);
Sub.prototype.constructor = Sub;
// 无论是基础 Vue类还是从基础 Vue类继承而来的类,都有一个cid属性,作为该类的唯一标识
Sub.cid = cid++;
// 子类和父类构造器的配置选项进行合并
Sub.options = mergeOptions(
Super.options,
extendOptions
);
// 构建的子类,会为Ctor添加一个super属性,指向其父类构造器
Sub['super'] = 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.
if (Sub.options.props) {
initProps$1(Sub);
}
if (Sub.options.computed) {
initComputed$1(Sub);
}
// allow further extension/mixin/plugin usage
Sub.extend = Super.extend;
Sub.mixin = Super.mixin;
Sub.use = Super.use;
// create asset registers, so extended classes
// can have their private assets too.
// ASSET_TYPES = [ 'component','directive','filter' ];
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.
Sub.superOptions = Super.options;
Sub.extendOptions = extendOptions;
Sub.sealedOptions = extend({}, Sub.options);
// cache constructor 缓存 构造器
cachedCtors[SuperId] = Sub;
// 返回子类构造函数
return Sub
}