八股文通关指南(一):彻底搞懂Vue生命周期

很多面试官在面试冷场或想快速过滤候选人时,总会抛出这道「经典八股文」作为「试金石」------ 「说说 Vue 组件的生命周期吧?」

表面是道基础题,实则暗藏玄机:

✅ 初级选手只能背出钩子顺序,

✅ 中级选手能结合场景讲用途,

✅ 高级选手却能从原理反推设计逻辑,让面试官眼前一亮。

如何在同质化回答中脱颖而出?

关键在于:拒绝模板化背诵,深挖底层逻辑

今天这篇文章,将带你从以下维度彻底搞懂生命周期

  1. 面试官的「潜台词」:这道题究竟在考察什么?
  2. 从「出生到死亡」的全流程:每个钩子的真实触发时机与设计意图
  3. 父子组件的「生命周期接力赛」:顺序背后的组件通信原理
  4. Vue3 组合式 API 变革:如何用 Hook 让逻辑复用更优雅
  5. 面试真题拆解:从「背答案」到「讲原理」的突围技巧

一、面试官的「潜台词」:这道题究竟在考察什么?

当面试官抛出「说说 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 钩子中修改状态会发生什么?」

  • 错误回答:「会立即触发新的更新」

  • 正确解析:

  1. updated钩子中修改状态会将变更推入更新队列
  2. 在下一个事件循环中,才会触发新的beforeUpdate→updated流程
  3. 极端情况下导致无限循环,建议用watch替代状态修改

3. 组件「临终时刻」:资源清理的最后防线

必做三件事:

  1. 清除定时器:clearInterval(this.timer)
  2. 解绑自定义事件:this.$off('custom-event')(Vue2)或在组合式 API 中通过onBeforeUnmount清理(Vue3)
  3. 销毁第三方实例: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」

高分回答(原理级):

  1. 现象:缓存组件不会触发 mounted/unmounted,因为未真正卸载,而是进入「休眠状态」
  2. 原理:keep-alive 通过 Vue 的内置组件缓存 VNode,重新激活时直接复用旧节点,仅触发状态钩子
  3. 场景:适合列表页切换(如商品列表→订单列表),保留表单输入状态,减少重复渲染

2. 挖坑题:「服务端渲染(SSR)会执行哪些生命周期?」

普通回答(模糊不清):

「好像只执行 created」

高分回答(细节控):

  1. 服务端阶段:仅执行beforeCreate和created(无 DOM 环境,无法执行挂载相关钩子

  2. 客户端激活阶段:

  • 先执行beforeMount→mounted完成真实 DOM 渲染
  • 若组件被 keep-alive 缓存,后续切换触发activated
  1. 注意点:避免在服务端钩子中使用浏览器专属 API(如document、window),会导致 SSR 报错

3. 进阶题:「如何在生命周期中优雅处理异步请求?」

普通回答(简单罗列):

「在 created 或 mounted 中用 axios 请求」

高分回答(工程化思维):

  • 非 DOM 依赖请求:优先在created中发起(减少 mounted 阶段阻塞)
  • DOM 依赖请求:必须在mounted中执行(如需要滚动条高度计算参数)

结语

希望本篇文章可以帮到在准备面试的各位,如果觉得文章还可以的麻烦点赞,收藏支持一下。另外欢迎大家留言讨论,或者想看啥面试题的也可以留言给我,希望大家多多支持!!

相关推荐
_r0bin_15 分钟前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
IT瘾君16 分钟前
JavaWeb:前端工程化-Vue
前端·javascript·vue.js
zhang988000016 分钟前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
potender18 分钟前
前端框架Vue
前端·vue.js·前端框架
站在风口的猪11081 小时前
《前端面试题:CSS预处理器(Sass、Less等)》
前端·css·html·less·css3·sass·html5
程序员的世界你不懂1 小时前
(9)-Fiddler抓包-Fiddler如何设置捕获Https会话
前端·https·fiddler
MoFe11 小时前
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
java·前端·.netcore
去旅行、在路上2 小时前
chrome使用手机调试触屏web
前端·chrome
Aphasia3112 小时前
模式验证库——zod
前端·react.js
lexiangqicheng3 小时前
es6+和css3新增的特性有哪些
前端·es6·css3