Vue 中 keep-alive 的作用和使用方式?

<keep-alive> 用于缓存组件实例,避免重复渲染,保留组件状态。

基本用法

<template>
  <!-- 缓存动态组件 -->
  <keep-alive>
    <component :is="currentComponent" />
  </keep-alive>

  <!-- 配合路由 -->
  <keep-alive>
    <router-view />
  </keep-alive>
</template>

属性

<!-- include:只缓存匹配的组件 -->
<keep-alive :include="['UserList', 'Dashboard']">
  <router-view />
</keep-alive>

<!-- exclude:不缓存匹配的组件 -->
<keep-alive :exclude="['Login']">
  <router-view />
</keep-alive>

<!-- max:最多缓存数量(LRU 算法) -->
<keep-alive :max="10">
  <router-view />
</keep-alive>

生命周期

被 keep-alive 缓存的组件有额外的生命周期:

import { onActivated, onDeactivated } from 'vue'

// 组件从缓存激活时调用
onActivated(() => {
  console.log('组件被激活')
  // 恢复滚动位置、重新请求数据等
})

// 组件被缓存(停用)时调用
onDeactivated(() => {
  console.log('组件被缓存')
  // 暂停定时器、保存状态等
})

实际应用

1. 列表页 → 详情页 → 返回列表页(保持滚动位置和筛选状态)

<!-- App.vue -->
<keep-alive :include="cachedViews">
  <router-view />
</keep-alive>
// 通过路由 meta 控制
const routes = [
  {
    path: '/list',
    component: List,
    meta: { keepAlive: true }  // 需要缓存
  },
  {
    path: '/detail/:id',
    component: Detail,
    meta: { keepAlive: false }
  }
]

2. 标签页切换保持状态

<keep-alive>
  <component :is="activeTab" />
</keep-alive>

注意事项

  1. keep-alive 只缓存有 name 的组件
<script setup>
// 需要 defineOptions 设置 name
defineOptions({ name: 'UserList' })
</script>
  1. 内存管理:缓存的组件保留在内存中,max 属性限制数量

  2. 数据更新问题:缓存后再次激活不会触发 onMounted,需要在 onActivated 中处理数据刷新

onActivated(() => {
  // 每次激活时检查是否需要刷新数据
  if (needRefresh.value) {
    fetchData()
  }
})
  1. Vue3 变化:<keep-alive> 的 include/exclude 支持字符串、正则、数组

同分类其他题目