• 1.4 子类构造器

    1.4 子类构造器

    选项校验介绍完后,在正式进入合并策略之前,还需要先了解一个东西:子类构造器。为什么需要先提到子类构造器呢?

    按照前面的知识,Vue内部提供了四个默认选项,关键的三个是components,directives,filter。那么当我们传递一个选项配置到Vue进行初始化,所需要合并的选项好像也仅仅是那关键的三个默认选项而已,那么源码中大篇幅做的选项合并策略又是针对什么场景呢?答案就是这个子类构造器。

    Vue提供了一个Vue.extend的静态方法,它是基于基础的Vue构造器创建一个“子类”,而这个子类所传递的选项配置会和父类的选项配置进行合并。这是选项合并场景的由来。

    因此有不要先了解子类构造器的实现。下面例子中,我们创建了一个Child的子类,它继承于父类Parent,最终将子类挂载到#app元素上。最终获取的data便是选项合并后的结果。

    1. var Parent = Vue.extend({
    2. data() {
    3. test: '父类'
    4. test1: '父类1'
    5. }
    6. })
    7. var Child = Parent.extend({
    8. data() {
    9. test: '子类',
    10. test2: '子类1'
    11. }
    12. })
    13. var vm = new Child().$mount('#app');
    14. console.log(vm.$data);
    15. // 结果
    16. {
    17. test: '子类',
    18. test1: '父类1',
    19. test2: '子类1'
    20. }

    Vue.extend的实现思路很清晰,创建了一个Sub的类,这个类的原型指向了父类,并且子类的options会和父类的options进行合并,mergeOptions的其他细节接下来会重点分析。

    1. Vue.extend = function (extendOptions) {
    2. extendOptions = extendOptions || {};
    3. var Super = this;
    4. var name = extendOptions.name || Super.options.name;
    5. if (name) {
    6. validateComponentName(name); // 校验子类的名称是否符合规范
    7. }
    8. // 创建子类构造器
    9. var Sub = function VueComponent (options) {
    10. this._init(options);
    11. };
    12. Sub.prototype = Object.create(Super.prototype); // 子类继承于父类
    13. Sub.prototype.constructor = Sub;
    14. Sub.cid = cid++;
    15. // 子类和父类构造器的配置选项进行合并
    16. Sub.options = mergeOptions(
    17. Super.options,
    18. extendOptions
    19. );
    20. return Sub // 返回子类构造函数
    21. };