← 返回题目列表

Vue 组件生命周期有哪些?Vue3 中如何使用?

高频 中等 第 9 / 27 题 更新于 2026/07/27
Vue生命周期Vue3

简化版

Vue 生命周期描述组件创建、挂载、更新、卸载的过程。Vue3 Composition API 中常用 onMountedonUpdatedonUnmountedonBeforeMountonBeforeUnmount 等钩子,副作用资源要在卸载时清理。

详细版

常见阶段:

  • 创建:初始化 props、state、响应式依赖。
  • 挂载:DOM 插入页面,onMounted 可访问 DOM。
  • 更新:响应式数据变化后重新渲染。
  • 卸载:组件从页面移除,清理事件、定时器、订阅。

Vue3 示例:

onMounted(() => {
  window.addEventListener('resize', onResize);
});

onUnmounted(() => {
  window.removeEventListener('resize', onResize);
});

面试重点不只是背钩子名,而是说清每个阶段适合做什么。

完整版教学

一、生命周期是组件资源管理模型

组件不是只渲染一次 HTML。它会创建状态、绑定事件、请求数据、响应更新,最后卸载。生命周期钩子给开发者在关键阶段插入逻辑的机会。

二、mounted 阶段适合访问 DOM

在 setup 执行时,DOM 还没挂载。需要测量元素尺寸、初始化图表、绑定依赖真实 DOM 的第三方库,通常放在 onMounted

const el = ref(null);
onMounted(() => {
  console.log(el.value);
});

三、updated 阶段要谨慎

onUpdated 在组件 DOM 更新后执行。如果在里面继续修改触发当前组件更新的数据,可能造成循环更新。

更常见的做法是用 computed/watch 精准处理数据变化,而不是在 updated 里做大量业务逻辑。

四、unmounted 阶段负责清理

定时器、全局事件、WebSocket、第三方库实例、订阅都要在卸载时清理。

这是前端内存泄漏高发点。组件创建了什么外部副作用,组件卸载时就应该释放什么。

五、面试追问与工程落地

生命周期常见追问是“setup 在哪个阶段”。在 Vue3 中,setup 发生在组件实例创建阶段,早于 mounted,里面还不能直接访问真实 DOM。它更像组合式逻辑入口,用来创建响应式状态、注册生命周期、准备方法。

还会问父子组件生命周期顺序。通常创建和挂载时,父组件先开始创建,子组件挂载完成后父组件才 mounted;卸载时父组件先触发 beforeUnmount,再卸载子组件,最后完成 unmounted。理解顺序有助于排查父子 DOM、订阅清理问题。

工程里副作用一定要成对管理:mounted 里添加的 window 事件,unmounted 里移除;创建的图表实例,卸载时 dispose;开启的轮询,卸载时 clear。生命周期的核心不是背钩子,而是资源生命周期闭环。

六、用父子时间线和资源闭环分析钩子

生命周期顺序应按“开始父工作 → 完成子树 → 完成父工作”理解,而不是孤立背名字。首次挂载时父组件先进入挂载准备,子组件完成挂载后父组件才 mounted;卸载则由父组件发起,清理整个子树后父组件最终完成卸载。具体业务不要依赖同级组件的偶然顺序,应通过数据流或显式事件协调。

挂载:父 beforeMount
        └─ 子 beforeMount → 子 mounted
           └──────────────→ 父 mounted

卸载:父 beforeUnmount
        └─ 子 beforeUnmount → 子 unmounted
           └────────────────→ 父 unmounted
阶段DOM 状态合适工作常见风险
setup尚无已挂载 DOM建状态、注册 hooks提前访问模板 ref
onMounted自身 DOM 已创建测量、初始化 DOM 库忘记 SSR 不执行该钩子
onUpdated本轮 DOM 已更新极少量更新后观察再改依赖造成循环
onUnmounted组件已卸载清理计时器、订阅和实例资源泄漏
onActivated/deactivatedKeepAlive 缓存切换暂停/恢复缓存页任务误以为会 unmounted

假设路由往返页面 50 次,每次 mounted 都新增 1 个 window resize 监听器却不移除,最终一次 resize 可能执行 50 份旧回调。把 add/remove、subscribe/unsubscribe、start/stop 成对放进组件生命周期,才能让资源数量始终回到 0 或 1。

异步请求也要考虑组件卸载。请求完成后若组件已离开,结果不应继续驱动无效逻辑;可以使用 AbortController、清理标记,或交给具备缓存和取消策略的数据层。生命周期钩子能管理资源边界,但不能自动取消所有异步工作。

onMounted(() => window.addEventListener('resize', onResize))
onUnmounted(() => window.removeEventListener('resize', onResize))

移除监听时事件目标、事件名和函数引用必须与注册时一致,因此不要在两处各写一个新的匿名函数。计时器、订阅和第三方实例也遵循同样的“保存句柄、原样释放”原则。

记忆钩子:组件创建了什么外部资源,就必须定义它在停用或卸载时如何释放;生命周期本质是资源所有权,不是钩子名考试。

七、常见误区与追问

  • 误区:setup 执行时模板 DOM 已经可用。 setup 是状态和逻辑准备阶段,模板 ref 通常要到 mounted 后才指向真实元素。
  • 误区:onUpdated 适合集中修改所有更新后的状态。 在其中继续修改参与渲染的数据可能触发新的更新甚至循环,应优先 computed 或精确 watch。
  • 误区:KeepAlive 切走组件一定会触发 onUnmounted。 缓存组件通常进入 deactivated,真正从缓存移除时才卸载。
  • 追问:父子 mounted 顺序是什么? 父先开始挂载流程,子 mounted 后父 mounted,确保父完成时其同步子树已挂载。
  • 追问:为什么全局事件一定要清理? 事件目标生命周期长于组件,遗留回调会持有组件数据并重复执行,形成泄漏和逻辑错误。
  • 追问:SSR 中 mounted 会执行吗? 服务端没有真实 DOM,mounted 类客户端钩子不在服务端渲染阶段执行,DOM 逻辑必须放客户端。
  • 追问:请求应该放 onMounted 还是 setup? 取决于是否依赖 DOM、SSR 和数据框架策略;请求并不天然必须等 mounted,应明确执行环境和取消方式。

八、加强记忆

生命周期不要死背,按职责记:mounted 访问 DOM,updated 看更新后结果,unmounted 清理副作用。创建和释放成对出现,是组件稳定性的关键。

再按父启动、子完成、父完成的顺序推演同步子树,遇到 KeepAlive 和 SSR 时单独说明边界。