KeepAlive
缓存组件实例,让组件切换后保留原来的状态
干什么用的?
<KeepAlive> 是 Vue 内置组件,用来缓存动态组件或路由组件。组件从页面上离开时不会被销毁,再次进入时可以复用原来的实例,因此表单内容、滚动位置和组件内部状态都能保留。
常见场景:
- Tab 切换:切回 Tab 时保留筛选条件和输入内容
- 列表与详情页:从详情返回列表时保留列表位置
- 多个编辑页:在不同编辑页之间切换时保留草稿
它不是“让组件一直显示”,而是把组件从 DOM 中移除,同时把实例放入缓存。
基本用法
缓存动态组件
也可以使用 include、exclude 精确控制哪些组件参与缓存:
include 和 exclude 支持组件名字符串、逗号分隔字符串、正则表达式和数组。include 优先表示“只缓存匹配的组件”,exclude 表示“匹配的组件不缓存”。
与生命周期的关系
组件首次进入时,仍然会正常执行 created、mounted(Vue 2)或 onMounted(Vue 3)。被缓存后:
- 离开当前视图:触发
deactivated/onDeactivated,组件实例不会销毁 - 再次进入视图:触发
activated/onActivated,组件实例会被复用 - 从缓存中真正移除:才会触发
beforeUnmount、unmounted(Vue 3)或对应的 Vue 2 销毁钩子
被缓存不等于所有资源都会自动暂停。定时器、轮询、WebSocket 和事件监听应在
onDeactivated中暂停或解绑,并在onActivated中恢复。
配置参数
max 与 LRU
KeepAlive 通常使用 LRU(Least Recently Used,最近最少使用)策略管理缓存:
- 命中缓存时,组件被标记为最近使用
- 新组件进入且缓存已满时,淘汰最久未使用的实例
- 被淘汰的实例会真正卸载,随后再次进入会重新创建
合理设置 max 可以避免缓存过多页面导致内存占用持续增长。
路由页面缓存
Vue Router 中通常把 RouterView 渲染出的组件包在 KeepAlive 内:
如果使用路由元信息决定是否缓存,可以这样写:
常见坑点
1. include 匹配的是组件名
匹配依据是组件的 name,不是路由的 name。使用 include 时要确认组件名与配置一致。Vue 2 中通常需要显式声明 name;Vue 3 <script setup> 可以使用 defineOptions({ name: 'UserList' }) 声明名称。
2. 参数变化不一定会重新创建组件
同一个路由组件仅是参数变化时,KeepAlive 可能继续复用实例。需要响应 route.params 或 route.query 的变化,必要时在 onActivated 中重新拉取数据。
3. 需要“刷新”时不能只依赖 KeepAlive
想强制重建组件,应改变组件的 key,或在业务层移除对应缓存后再进入。不要为了刷新而随意给整个页面树增加随机 key,否则会失去缓存收益。
4. 缓存状态与服务端数据不是一回事
KeepAlive 只缓存前端组件实例,不会自动保证数据最新。回到页面时是否请求接口,应根据数据时效性在 onActivated、路由守卫或状态管理层中明确处理。

