标准答案

  1. keep-alive 是 Vue 内置组件,常用于缓存动态组件或路由组件实例。组件被切走时不会直接卸载,而是进入缓存。
  2. 被缓存的组件再次显示时,会复用之前的组件实例、响应式状态和 DOM 子树,不会重新走完整 mounted 流程。
  3. activated 会在缓存组件被激活时触发,deactivated 会在缓存组件被切走时触发。需要恢复轮询、刷新数据、暂停监听时可以用这两个钩子。
  4. include 和 exclude 用来按组件 name 控制哪些组件参与缓存。max 可以限制最多缓存多少个实例,超出后会按缓存策略移除旧实例。
  5. 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,导致缓存规则不生效。

作者信息