高频面试题:
Vue中嵌套组件生命周期的执行顺序是什么?
先看个例子:
const child = {
template: `<div>child-component</div>`,
beforeCreate() {
console.log('child-beforeCreate')
},
created() {
console.log('child-created')
},
beforeMount() {
console.log('child-beforeMount')
},
mounted() {
console.log('child-mounted')
},
beforeDestroy() {
console.log('child-beforeDestroy')
},
destroyed() {
console.log('child-destroyed')
},
beforeUpdate() {
console.log('child-beforeUpdate')
},
updated() {
console.log('child-updated')
},
}
const app = {
template: `<div @click='changeNum'><child>app-component</child><span>count:{{num}}</span></div>`,
data() {
return {
num: 0,
}
},
components: {
child
},
beforeCreate() {
console.log('app-beforeCreate')
},
created() {
console.log('app-created')
},
beforeMount() {
console.log('app-beforeMount')
},
mounted() {
console.log('app-mounted')
},
beforeDestroy() {
console.log('app-beforeDestroy')
},
destroyed() {
console.log('app-destroyed')
},
beforeUpdate() {
console.log('app-beforeUpdate')
},
updated() {
console.log('app-updated')
},
methods: {
changeNum() {
this.num++;
}
},
}
new Vue({
el: "#app",
template: `<div>
<div><app v-if="isShow"></app></div>
<button @click='changeStaus'>切换状态</button>
</div>`,
data() {
return {
isShow: true,
}
},
components: {
app,
},
methods: {
changeStaus() {
this.isShow = !this.isShow
},
}
});
1、beforeCreate、created、beforeMount和mounted
当前例子首次渲染时,打印的信息为:
执行逻辑如下所示:
从例子打印信息和图示逻辑中可以看出,beforeCreate、created和beforeMount的执行顺序是先父后子,而mounted是先子后父。
父组件app执行完beforeMount生命周期后,就进入了子组件child的渲染,子组件的渲染过程和父组件相似,所以又会执行一遍渲染前的生命周期beforeCrzeate、created和beforeMount,等到子组件组件节点渲染完成后,会执行当前子组件的mounted。子组件的渲染的渲染完成以后,当前层级的递归结束,执行逻辑交给父组件app,继续执行父组件的mounted生命周期钩子函数。
2、beforeUpdate和updated
点击父组件修改数据时,打印的信息为:
从执行打印可以看出,beforeUpdate是先父后子,updated是先子后父。
3、beforeDestroy和destroyed
点击将控制父组件的显示隐藏条件为false时,打印的信息为:
从执行打印可以看出,beforeDestroy是先父父后子,destroyed是先子后父。
总结:
文中除了mounted、updated和destroyed执行顺序是先子后父,其他生命周期执行顺序是先父后子。