1.4 子类构造器
选项校验介绍完后,在正式进入合并策略之前,还需要先了解一个东西:子类构造器。为什么需要先提到子类构造器呢?
按照前面的知识,Vue
内部提供了四个默认选项,关键的三个是components,directives,filter
。那么当我们传递一个选项配置到Vue
进行初始化,所需要合并的选项好像也仅仅是那关键的三个默认选项而已,那么源码中大篇幅做的选项合并策略又是针对什么场景呢?答案就是这个子类构造器。
Vue
提供了一个Vue.extend
的静态方法,它是基于基础的Vue
构造器创建一个“子类”,而这个子类所传递的选项配置会和父类的选项配置进行合并。这是选项合并场景的由来。
因此有不要先了解子类构造器的实现。下面例子中,我们创建了一个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);
// 结果
{
test: '子类',
test1: '父类1',
test2: '子类1'
}
Vue.extend
的实现思路很清晰,创建了一个Sub
的类,这个类的原型指向了父类,并且子类的options
会和父类的options
进行合并,mergeOptions
的其他细节接下来会重点分析。
Vue.extend = function (extendOptions) {
extendOptions = extendOptions || {};
var Super = this;
var name = extendOptions.name || Super.options.name;
if (name) {
validateComponentName(name); // 校验子类的名称是否符合规范
}
// 创建子类构造器
var Sub = function VueComponent (options) {
this._init(options);
};
Sub.prototype = Object.create(Super.prototype); // 子类继承于父类
Sub.prototype.constructor = Sub;
Sub.cid = cid++;
// 子类和父类构造器的配置选项进行合并
Sub.options = mergeOptions(
Super.options,
extendOptions
);
return Sub // 返回子类构造函数
};