1.8 生命周期钩子函数的合并
在学习Vue
时,有一个重要的思想,生命周期。它是我们使用Vue
高效开发组件的基础,我们可以在组件实例的不同阶段去定义需要执行的函数,让组件的功能更加丰富。在介绍生命周期钩子函数的选项合并前,我们有必要复习以下官方的生命周期图。
然而从源码中我们可以看到Vue
的生命周期钩子不止这些,它有多达12个之多,每个钩子的执行时机我们暂且不深究,它们会在以后的章节中逐一出现。我们关心的是:子父组件的生命周期钩子函数是遵循什么样的规则合并。
var LIFECYCLE_HOOKS = [
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
'activated',
'deactivated',
'errorCaptured',
'serverPrefetch'
];
LIFECYCLE_HOOKS.forEach(function (hook) {
strats[hook] = mergeHook; // 对生命周期钩子选项的合并都执行mergeHook策略
});
mergeHook
是生命周期钩子合并的策略,简单的对代码进行总结,钩子函数的合并原则是:
- 如果子类和父类都拥有相同钩子选项,则将子类选项和父类选项合并。
- 如果父类不存在钩子选项,子类存在时,则以数组形式返回子类钩子选项。
- 当子类不存在钩子选项时,则以父类选项返回。
- 子父合并时,是将子类选项放在数组的末尾,这样在执行钩子时,永远是父类选项优先于子类选项执行。
// 生命周期钩子选项合并策略
function mergeHook (
parentVal,
childVal
) {
// 1.如果子类和父类都拥有钩子选项,则将子类选项和父类选项合并,
// 2.如果父类不存在钩子选项,子类存在时,则以数组形式返回子类钩子选项,
// 3.当子类不存在钩子选项时,则以父类选项返回。
var res = childVal ? parentVal ? parentVal.concat(childVal) : Array.isArray(childVal) ? childVal : [childVal] : parentVal;
return res
? dedupeHooks(res)
: res
}
// 防止多个组件实例钩子选项相互影响
function dedupeHooks (hooks) {
var res = [];
for (var i = 0; i < hooks.length; i++) {
if (res.indexOf(hooks[i]) === -1) {
res.push(hooks[i]);
}
}
return res
}
下面结合具体的例子看合并结果。
var Parent = Vue.extend({
mounted() {
console.log('parent')
}
})
var Child = Parent.extend({
mounted() {
console.log('child')
}
})
var vm = new Child().$mount('#app');
// 输出结果:
parent
child
简单总结一下:对于生命周期钩子选项,子类和父类相同的选项将合并成数组,这样在执行子类钩子函数时,父类钩子选项也会执行,并且父会优先于子执行。