前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Vue KeepAlive onActivated onDeactivated 缓存组件
VuVue侦听与生命周期

Vue KeepAlive 为什么要用 onActivated 和 onDeactivated?

缓存保留了实例和本地状态,因此“暂时离开界面”和“永久销毁”必须成为两个动作。

前端进阶之旅 · 一题精讲更新于 2026.09.06
Vue#侦听与生命周期#缓存
先看核心答案读代码示例
理解线索

一个缓存实例有两层生命周期

  1. 可见活动期插入缓存树对应位置,允许运行可见期任务
  2. 缓存失活期从节点树移开但保留组件实例与状态
  3. 最终结束被缓存淘汰或父树销毁,实例真正卸载

后代组件也可能收到缓存树的激活与失活钩子,资源 owner 仍要避免多层重复操作同一实例。

核心回答

先记住这个答案

被 KeepAlive 缓存的组件切走时进入 deactivated,不会像普通动态组件那样立即 unmounted;切回来时 activated,原实例与本地状态继续使用。onActivated 也会在首次挂载时调用,onDeactivated 也会在最终卸载时调用。只在可见期需要的轮询、媒体或快捷键可在 activated 启动、deactivated 停止;必须保留的缓存状态不要在失活时清空。最终资源关闭仍应保证幂等,并考虑缓存 max 淘汰。

  • 失活表示缓存而非实例销毁
  • activated 包含首次挂载,deactivated 包含最终卸载
  • 按可见期暂停资源,按实例寿命保存状态

普通挂载卸载不足以描述缓存切换

没有 KeepAlive 时,动态组件切走会卸载,切回创建新实例。缓存后目标正是保留输入、滚动或局部计算结果,所以切换过程不能继续按销毁和重建处理。

如果轮询只在组件可见时有意义,却只在 unmounted 才停止,它会在缓存期间持续请求。反过来,如果失活时把表单状态全部重置,又违背了使用缓存保留状态的目的。

让可见期任务具有幂等 start 和 stop

下例在 activated 中增加活动标记,在 deactivated 中移除。真实任务可以替换为事件订阅或播放控制,但 start 必须避免重复注册,stop 也要允许最终卸载路径再次调用。

事件记录可以验证首次挂载会出现 activated,切到另一个组件会出现 deactivated,切回又出现 activated。不要只期待第二次进入缓存时才调用激活钩子。

记录缓存组件的激活与失活TypeScript
import { h, onActivated, onDeactivated, ref } from 'vue'

const keepAliveEvents: string[] = []
const active = ref(false)
const CachedPanel = {
  name: 'CachedPanel',
  setup() {
    onActivated(() => {
      active.value = true
      keepAliveEvents.push('activated')
    })
    onDeactivated(() => {
      active.value = false
      keepAliveEvents.push('deactivated')
    })
    return () => h('span', active.value ? 'active' : 'inactive')
  }
}

将 CachedPanel 放入 KeepAlive 的动态分支后,首次显示记录 activated,切走记录 deactivated,切回再记录 activated。active 是演示状态,真实组件应避免钩子写入造成无意义的额外渲染。

缓存淘汰仍会走最终结束

KeepAlive 的 max 类似最近使用缓存限制,容量超出时旧实例会被销毁。应用不能假定进入缓存后永远存在,关键草稿应有更持久的保存策略,资源也要能在最终结束时释放。

某项共享订阅若同时服务多个缓存组件,应交给独立服务和引用计数,不能由任意一个组件 deactivated 就整体关闭。可见期订阅与跨组件共享服务的生命周期需要分层。

回答前,多想一步

容易答错的地方

只写 mounted 和 unmounted 控制轮询
缓存切走不一定卸载,轮询会继续;切回也不会再次 mounted,无法重新启动。可见期工作应使用 activated 与 deactivated,永久资源再按组件结束处理。
在 deactivated 中清空所有本地状态
KeepAlive 的主要价值就是保留实例状态。只暂停与不可见相关的副作用,是否重置数据应由产品语义决定,不能把失活误当成完整销毁。
试着用自己的话回答

面试官还会怎么问?

onDeactivated 在最终卸载时也会调用吗?

会。缓存实例最终卸载时也会进入该钩子,因此停止函数应幂等,避免与 onUnmounted 的另一条清理重复调用同一资源后抛错。

后代组件也能收到这些钩子吗?

缓存根组件以及其缓存树中的后代都可以注册激活与失活钩子。若多层操作同一共享资源,应明确唯一 owner,防止重复启动和停止。

缓存组件中的 watch 会自动暂停吗?

不能假定所有响应式效果因 deactivated 自动停止。实例仍被保留,需要根据业务在失活钩子中暂停昂贵任务,或让 watch 自己检查可见状态并正确清理。

从一道题,走向一组知识

把知识连起来

侦听与生命周期

Vue 组件卸载时,定时器和全局事件应该在哪个钩子清理?

永久卸载清理与缓存期间暂停需要分别设计。

侦听与生命周期

如何用 Vue effectScope 实现跨组件共享且可回收的副作用?

多个缓存组件共享资源时,可用独立 owner 和引用计数管理。

侦听与生命周期

Vue 组合式 API 生命周期钩子与选项式 API 如何对应?

缓存钩子属于常规挂载更新卸载之外的生命周期分支。

参考资料

  • Vue:缓存实例生命周期
  • Vue:onActivated

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 普通挂载卸载不足以描述缓存切换
  3. 让可见期任务具有幂等 start 和 stop
  4. 缓存淘汰仍会走最终结束
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑