标准答案
- keep-alive 是 Vue 内置组件,常用于缓存动态组件或路由组件实例。组件被切走时不会直接卸载,而是进入缓存。
- 被缓存的组件再次显示时,会复用之前的组件实例、响应式状态和 DOM 子树,不会重新走完整 mounted 流程。
- activated 会在缓存组件被激活时触发,deactivated 会在缓存组件被切走时触发。需要恢复轮询、刷新数据、暂停监听时可以用这两个钩子。
- include 和 exclude 用来按组件 name 控制哪些组件参与缓存。max 可以限制最多缓存多少个实例,超出后会按缓存策略移除旧实例。
- keep-alive 适合列表页返回保留筛选、Tab 切换保留输入、步骤页面保留局部状态;不适合缓存必须每次重新初始化或包含敏感状态的页面。
题目解析
这题要把“缓存实例”和“隐藏 DOM”区分开。keep-alive 缓存的是组件实例,v-show 只是控制显示隐藏。
被 keep-alive 缓存的组件不会在每次切换时触发 unmounted,因此清理副作用不能只依赖 onUnmounted。
路由缓存时要注意组件 name、路由 key 和 include / exclude 的匹配,否则看起来写了缓存,实际没有命中。
代码示例
这个例子展示动态组件缓存,以及在激活和停用时处理副作用。
Vue
<script setup lang="ts">
import { onActivated, onDeactivated, ref } from 'vue'
const currentTab = ref<'profile' | 'orders'>('profile')
onActivated(() => {
console.log('页面回到前台,可以刷新轻量数据')
})
onDeactivated(() => {
console.log('页面进入缓存,可以暂停轮询')
})
</script>
<template>
<button type="button" @click="currentTab = 'profile'">资料</button>
<button type="button" @click="currentTab = 'orders'">订单</button>
<KeepAlive include="ProfileTab,OrdersTab" :max="5">
<component :is="currentTab === 'profile' ? ProfileTab : OrdersTab" />
</KeepAlive>
</template>常见误区
- 认为 keep-alive 只是隐藏组件。它缓存的是组件实例和状态。
- 被缓存组件切走后还继续轮询或监听,没有在 deactivated 中暂停。
- include 写了组件名但组件没有 name,导致缓存规则不生效。