在使用 <KeepAlive> 缓存组件时,你会经常遇到三个核心属性:include、exclude 和 max。它们让你能精确控制哪些组件实例值得缓存,以及缓存的容量上限,避免内存无限增长。
1. include 和 exclude
include 和 exclude 都接受一个以逗号分隔的组件名称字符串、正则表达式或一个名称数组。它们匹配的是组件的 name 选项,而不是文件路径或标签名。
- include:只缓存名称匹配的组件。
- exclude:排除名称匹配的组件,其余都缓存。
这两个属性可以同时使用,但 exclude 的优先级更高:如果一个组件同时满足 include 和 exclude,它不会被缓存。
典型写法
<!-- 只缓存名为 Home 和 About 的组件 -->
<KeepAlive include="Home,About">
<component :is="currentTab" />
</KeepAlive>
<!-- 不缓存 Login 和 Register -->
<KeepAlive :exclude="['Login', 'Register']">
<router-view />
</KeepAlive>
<!-- 缓存所有名称以 View 结尾的组件(正则) -->
<KeepAlive :include="/View$/">
<router-view />
</KeepAlive>
<!-- 结合路由 meta 动态控制 -->
<template>
<KeepAlive :include="cachedViews">
<router-view />
</KeepAlive>
</template>
<script setup>
import { computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const cachedViews = computed(() =>
router.getRoutes()
.filter(r => r.meta.keepAlive)
.map(r => r.name)
.filter(Boolean)
)
</script>
常见场景:后台管理系统中,标签页切换或侧边栏菜单切换时,用户期望表单已填内容不丢失(如搜索条件、滚动位置)。你只需给对应的页面组件设置 name,再在路由 meta 中添加 keepAlive: true,然后在 <KeepAlive> 中动态生成 include 列表即可。
2. max — 缓存数量上限
max 是一个数字,限制最多缓存的组件实例数量。当缓存的实例个数即将超过该值时,Vue 会销毁最久没有被访问的那个缓存实例(LRU 算法)。
<!-- 最多缓存 10 个组件实例 -->
<KeepAlive :max="10">
<router-view />
</KeepAlive>
这个属性在无限打开新标签页的后台系统中尤为重要。如果没有 max,每打开一个新的标签页就会缓存一个新实例,内存占用会持续增长,最终可能导致页面卡顿。通过设置一个合理的 max(例如 10 或 20),可以确保只有最近使用的页面被保留,旧页面自动释放。
实用技巧:max 的值可以根据设备内存动态调整。你不需要精确计算,通常保持默认的“无上限”只有在组件数量可控时才安全,一旦是用户可无限新增的页面(如订单详情、聊天窗口),务必加上 max。
3. 不使用 include/exclude 的默认行为
如果不写 include 或 exclude,<KeepAlive> 会缓存所有直接子组件中当前显示的那个(或那些)。但有一个前提:被切换的组件必须设置了 name,否则 Vue 无法识别和匹配。如果你发现缓存不生效,第一步就是去检查组件的 name 是否定义正确。
<!-- 子组件必须有 name 选项 -->
<script>
export default {
name: 'MyComponent'
}
</script>
对于使用了 <script setup> 语法糖的组件,可以通过添加一个普通的 <script> 块来指定 name:
<script>
export default { name: 'MyComponent' }
</script>
<script setup>
// 组件逻辑
</script>
或者直接使用插件 vite-plugin-vue-setup-extend 让 <script setup> 支持 name 属性。
总结:include 和 exclude 提供了缓存粒度的控制,max 提供了缓存容量的控制。这三者组合使用,就能让 <KeepAlive> 在提升用户体验(保留页面状态)与保持内存健康之间找到最佳平衡。