很多面试官在面试冷场或想快速过滤候选人时,总会抛出这道「经典八股文」作为「试金石」------ 「说说 Vue 组件的生命周期吧?」
表面是道基础题,实则暗藏玄机:
✅ 初级选手只能背出钩子顺序,
✅ 中级选手能结合场景讲用途,
✅ 高级选手却能从原理反推设计逻辑,让面试官眼前一亮。
如何在同质化回答中脱颖而出?
关键在于:拒绝模板化背诵,深挖底层逻辑。
今天这篇文章,将带你从以下维度彻底搞懂生命周期:
- 面试官的「潜台词」:这道题究竟在考察什么?
- 从「出生到死亡」的全流程:每个钩子的真实触发时机与设计意图
- 父子组件的「生命周期接力赛」:顺序背后的组件通信原理
- Vue3 组合式 API 变革:如何用 Hook 让逻辑复用更优雅
- 面试真题拆解:从「背答案」到「讲原理」的突围技巧
一、面试官的「潜台词」:这道题究竟在考察什么?
当面试官抛出「说说 Vue 组件的生命周期」这个问题时,表面是在考察基础概念,实则暗藏三层「筛选逻辑」:
1. 第一层:是否具备基础认知(及格线)
- 基础要求:能准确说出Vue2和Vue3的各个生命周期钩子和执行的顺序
- 常见错误:Vue3的onBeforeUnmount与Vue2的beforeDestory混淆了,或者遗漏了某些生命周期钩子
2. 第二层:能否结合场景讲清用途(进阶级)
加分项:能举例说明钩子的实际应用
例如:
"在created钩子中发起API请求,因为此时数据观测已完成且无DOM阻塞,比如电商详情页加载商品数据;而mounted适合初始化依赖DOM的插件,比如在图表组件中调用echarts.init(this.$refs.chart)"
当然这个答案不唯一,各位可以根据自己的项目经验去回答
3. 第三层:是否理解底层设计逻辑(专家级)
终极考点:钩子机制如何体现 Vue 的设计哲学
- 异步更新队列:为什么updated钩子中修改状态会导致死循环?(因为会触发新的更新队列)
- 组件通信规则:父子组件生命周期顺序如何影响数据传递?(子组件mounted先于父组件,适合子组件主动暴露 DOM 引用)
二、从「出生到死亡」:生命周期全流程解析
Vue2生命周期示意图

Vue3生命周期示意图

全流程解析
1. 组件「出生阶段」:从内存到 DOM 的跨越
钩子触发顺序:
beforeCreate(Vue2)/ setup(Vue3) → created → beforeMount → mounted
核心原理揭秘:
- beforeCreate更早执行,是组合式 API 的逻辑入口,此时尚未创建this上下文
- created:Vue 完成数据观测(Object.defineProperty/Proxy)和事件初始化,可访问data但无$el
js
// 正确用法:初始化非DOM相关逻辑
created() {
this.timer = setInterval(() => console.log('tick'), 1000);
}
- mounted:真实 DOM 渲染完成,$el指向真实节点,标志着「浏览器环境专属逻辑」的开始
js
// 典型场景:初始化第三方库
mounted() {
this.$refs.input.focus(); // 操作DOM
this.chart = echarts.init(this.$refs.chartContainer); // 初始化图表
}
2. 组件「中年危机」:数据更新的「蝴蝶效应」
钩子触发条件: 当响应式数据(如data、props)发生变化时,按以下顺序触发:
beforeUpdate → 虚拟DOM diff → DOM更新 → updated
面试高频陷阱:
-
问题:「在 updated 钩子中修改状态会发生什么?」
-
错误回答:「会立即触发新的更新」
-
正确解析:
- updated钩子中修改状态会将变更推入更新队列
- 在下一个事件循环中,才会触发新的beforeUpdate→updated流程
- 极端情况下导致无限循环,建议用watch替代状态修改
3. 组件「临终时刻」:资源清理的最后防线
必做三件事:
- 清除定时器:
clearInterval(this.timer)
- 解绑自定义事件:
this.$off('custom-event')
(Vue2)或在组合式 API 中通过onBeforeUnmount清理(Vue3) - 销毁第三方实例:
this.chart.dispose()
(如地图、图表组件)
三、父子组件「生命周期接力赛」:顺序决定通信规则
1. 挂载阶段:深度优先的「递归哲学」
执行顺序(以二级组件为例):
js
父 beforeCreate → 父 created → 父 beforeMount
↓
子 beforeCreate → 子 created → 子 beforeMount → 子 mounted
↓
父 mounted
面试真题:「父组件 mounted 钩子中能否访问子组件的 $refs?」
- 正确答案:能,因为子组件的 mounted 先于父组件执行,此时子组件 DOM 已渲染完成
- 延伸考点:若子组件是异步组件(如通过 import () 动态加载),父组件 mounted 会先于子组件,需通过$nextTick确保子组件加载完成
2. 更新阶段:数据变化的「涟漪效应」
触发逻辑:
当父组件 props 变化时,按以下顺序更新:
父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated
实战应用:
- 子组件在beforeUpdate中缓存旧值,用于变更对比
js
beforeUpdate() {
this.oldProps = this.$props; // 缓存旧props
}
父组件在updated中执行依赖子组件更新后的逻辑(需通过$nextTick)
3. 卸载阶段:从子到父的「逆向销毁」
执行顺序:
父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted
关键提醒:
- 避免在父组件beforeUnmount中直接操作子组件状态,此时子组件可能已进入销毁流程
- 若子组件包含keep-alive缓存,卸载阶段会触发deactivated而非unmounted
四、Vue3 组合式 API:当生命周期遇上函数式编程
1.钩子名称「大迁徙」(Vue2→Vue3 对比表)

五、真题拆解:从「背答案」到「讲原理」的突围技巧
1. 经典题:「keep-alive 缓存的组件会触发哪些钩子?」
普通回答(模板化):
「会触发 activated 和 deactivated」
高分回答(原理级):
- 现象:缓存组件不会触发 mounted/unmounted,因为未真正卸载,而是进入「休眠状态」
- 原理:keep-alive 通过 Vue 的内置组件缓存 VNode,重新激活时直接复用旧节点,仅触发状态钩子
- 场景:适合列表页切换(如商品列表→订单列表),保留表单输入状态,减少重复渲染
2. 挖坑题:「服务端渲染(SSR)会执行哪些生命周期?」
普通回答(模糊不清):
「好像只执行 created」
高分回答(细节控):
-
服务端阶段:仅执行beforeCreate和created(无 DOM 环境,无法执行挂载相关钩子
-
客户端激活阶段:
- 先执行beforeMount→mounted完成真实 DOM 渲染
- 若组件被 keep-alive 缓存,后续切换触发activated
- 注意点:避免在服务端钩子中使用浏览器专属 API(如document、window),会导致 SSR 报错
3. 进阶题:「如何在生命周期中优雅处理异步请求?」
普通回答(简单罗列):
「在 created 或 mounted 中用 axios 请求」
高分回答(工程化思维):
- 非 DOM 依赖请求:优先在created中发起(减少 mounted 阶段阻塞)
- DOM 依赖请求:必须在mounted中执行(如需要滚动条高度计算参数)
结语
希望本篇文章可以帮到在准备面试的各位,如果觉得文章还可以的麻烦点赞,收藏支持一下。另外欢迎大家留言讨论,或者想看啥面试题的也可以留言给我,希望大家多多支持!!