Vue 3 SFC 实现 keep-alive 缓存需正确包裹于 <keep-alive> 内作为直接子组件,确保组件有明确 name(自动或手动设置),通过 include/exclude/max 精准控制缓存范围,并在 activated/deactivated 钩子中响应状态。

Vue 3 单文件组件(SFC)要实现 keep-alive 缓存状态,关键不是“在组件内部写什么”,而是**正确包裹 + 合理配置 + 响应生命周期**。它不依赖组件自身代码改动,而取决于父级如何使用 <keep-alive>,以及组件是否满足缓存识别条件。
必须包裹在 keep-alive 内部
单文件组件本身不能“自动被缓存”,它必须被 <keep-alive> 作为直接子元素包裹,且只能有一个直接子组件:
- ✅ 正确(动态组件场景):
<keep-alive><br> <component :is="currentView" /><br></keep-alive>
- ✅ 正确(路由场景,推荐写法):
<router-view v-slot="{ Component }"><br> <keep-alive><br> <component :is="Component" /><br> </keep-alive><br></router-view> - ❌ 错误:多层嵌套或多个兄弟节点
<keep-alive><br> <div><MyComponent /></div> <!-- 包裹了 div,不是直接子组件 --><br></keep-alive>
此时MyComponent不会被缓存,<keep-alive>只处理第一个直接子 vnode。
组件必须有可识别的 name
keep-alive 通过组件的 name 字符串匹配 include/exclude,所以单文件组件需确保有明确名称:
- 使用
<script setup>时(Vue ≥ 3.2.34),默认按文件名生成name(如UserInfo.vue→UserInfo),通常无需手动写; - 若需显式控制(比如文件名含下划线、想统一命名),可加
defineOptions({ name: 'UserProfile' }); - 使用 Options API 时,直接写
export default { name: 'UserProfile', ... }。
用 include/exclude 精准控制缓存范围
避免无差别缓存所有页面。在 <keep-alive> 上设置属性即可:
立即学习“前端免费学习笔记(深入)”;
- 只缓存特定组件:
<keep-alive :include="['UserList', 'UserDetail']"><br> <component :is="currentView" /><br></keep-alive>
- 排除某些组件(如带表单草稿的编辑页,每次进都应重置):
<keep-alive :exclude="['PostEdit']"><br> <component :is="currentView" /><br></keep-alive>
- 限制最多缓存 5 个实例(LRU 淘汰):
<keep-alive :max="5">...</keep-alive>
在组件内响应 activated/deactivated 钩子
缓存组件不会触发 mounted/unmounted,但会触发专属钩子,适合做状态同步、滚动恢复等:
- 使用组合式 API:
import { onActivated, onDeactivated } from 'vue'<br>onActivated(() => {<br> console.log('组件被激活,回到前台')<br> // 比如:恢复上次滚动位置、重新拉取更新数据<br>})<br>onDeactivated(() => {<br> console.log('组件被停用,切走了')<br> // 比如:保存当前滚动位置、暂停轮询<br>}) - 使用 Options API:
export default {<br> activated() { /* ... */ },<br> deactivated() { /* ... */ }<br>}


















