• 1.5 合并策略
    • 1.5.1 默认策略

    1.5 合并策略

    合并策略之所以是难点,其中一个是合并选项类型繁多,合并规则随着选项的不同也呈现差异。概括起来思路主要是以下两点:

    1. Vue针对每个规定的选项都有定义好的合并策略,例如data,component,mounted等。如果合并的子父配置都具有相同的选项,则只需要按照规定好的策略进行选项合并即可。
    2. 由于Vue传递的选项是开放式的,所有也存在传递的选项没有自定义选项的情况,这时候由于选项不存在默认的合并策略,所以处理的原则是有子类配置选项则默认使用子类配置选项,没有则选择父类配置选项。

    我们通过这两个思想去分析源码的实现,先看看mergeOptions除了规范检测后的逻辑。

    1. function mergeOptions ( parent, child, vm ) {
    2. ···
    3. var options = {};
    4. var key;
    5. for (key in parent) {
    6. mergeField(key);
    7. }
    8. for (key in child) {
    9. if (!hasOwn(parent, key)) {
    10. mergeField(key);
    11. }
    12. }
    13. function mergeField (key) {
    14. // 如果有自定义选项策略,则使用自定义选项策略,否则选择使用默认策略。
    15. var strat = strats[key] || defaultStrat;
    16. options[key] = strat(parent[key], child[key], vm, key);
    17. }
    18. return options
    19. }

    两个for循环规定了合并的顺序,以自定义选项策略优先,如果没有才会使用默认策略。而strats下每个key对应的便是每个特殊选项的合并策略

    1.5.1 默认策略

    我们可以用丰富的选项去定义实例的行为,大致可以分为以下几类:

    1. data,props,computed等选项定义实例数据
    2. mounted, created, destoryed等定义生命周期函数
    3. components注册组件
    4. methods选项定义实例方法

    当然还有诸如watch,inject,directives,filter等选项,总而言之,Vue提供的配置项是丰富的。除此之外,我们也可以使用没有默认配置策略的选项,典型的例子是状态管理Vuex和配套路由vue-router的引入:

    1. new Vue({
    2. store, // vuex
    3. router// vue-router
    4. })

    不管是插件也好,还是用户自定义的选项,他们的合并策略会遵循思路的第二点:子配置存在则取子配置,不存在则取父配置,即用子去覆盖父。。它的描述在defaultStrat中。

    1. // 用户自定义选项策略
    2. var defaultStrat = function (parentVal, childVal) {
    3. // 子不存在则用父,子存在则用子配置
    4. return childVal === undefined
    5. ? parentVal
    6. : childVal
    7. };

    接下来会进入某些具体的合并策略的分析,大致分为五类:

    1. 常规选项合并

    2. 自带资源选项合并

    3. 生命周期钩子合并

    4. watch选项合并

    5. props,methods, inject, computed类似选项合并