1.5 合并策略
合并策略之所以是难点,其中一个是合并选项类型繁多,合并规则随着选项的不同也呈现差异。概括起来思路主要是以下两点:
Vue
针对每个规定的选项都有定义好的合并策略,例如data,component,mounted
等。如果合并的子父配置都具有相同的选项,则只需要按照规定好的策略进行选项合并即可。- 由于
Vue
传递的选项是开放式的,所有也存在传递的选项没有自定义选项的情况,这时候由于选项不存在默认的合并策略,所以处理的原则是有子类配置选项则默认使用子类配置选项,没有则选择父类配置选项。
我们通过这两个思想去分析源码的实现,先看看mergeOptions
除了规范检测后的逻辑。
function mergeOptions ( parent, child, vm ) {
···
var options = {};
var key;
for (key in parent) {
mergeField(key);
}
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key);
}
}
function mergeField (key) {
// 如果有自定义选项策略,则使用自定义选项策略,否则选择使用默认策略。
var strat = strats[key] || defaultStrat;
options[key] = strat(parent[key], child[key], vm, key);
}
return options
}
两个for
循环规定了合并的顺序,以自定义选项策略优先,如果没有才会使用默认策略。而strats
下每个key
对应的便是每个特殊选项的合并策略
1.5.1 默认策略
我们可以用丰富的选项去定义实例的行为,大致可以分为以下几类:
- 用
data,props,computed
等选项定义实例数据 - 用
mounted, created, destoryed
等定义生命周期函数 - 用
components
注册组件 - 用
methods
选项定义实例方法
当然还有诸如watch,inject,directives,filter
等选项,总而言之,Vue
提供的配置项是丰富的。除此之外,我们也可以使用没有默认配置策略的选项,典型的例子是状态管理Vuex
和配套路由vue-router
的引入:
new Vue({
store, // vuex
router// vue-router
})
不管是插件也好,还是用户自定义的选项,他们的合并策略会遵循思路的第二点:子配置存在则取子配置,不存在则取父配置,即用子去覆盖父。。它的描述在defaultStrat
中。
// 用户自定义选项策略
var defaultStrat = function (parentVal, childVal) {
// 子不存在则用父,子存在则用子配置
return childVal === undefined
? parentVal
: childVal
};
接下来会进入某些具体的合并策略的分析,大致分为五类:
1. 常规选项合并
2. 自带资源选项合并
3. 生命周期钩子合并
4. watch
选项合并
5. props,methods, inject, computed
类似选项合并