缓存组件(keep-alive)使用详情

<keep-alive> 是 Vue 提供的内置组件,用于缓存包裹的组件实例,避免组件频繁创建和销毁带来的性能开销。它不会渲染成真实 DOM,仅作为一个 “容器” 管理内部组件的缓存状态。

一、基本用法

通过包裹动态组件(component 标签)或路由组件(router-view),实现组件缓存:

1. 缓存动态组件

vue

<template>
  <div>
    <button @click="currentComponent = 'ComponentA'">显示A</button>
    <button @click="currentComponent = 'ComponentB'">显示B</button>
    
    <!-- 缓存包裹的组件 -->
    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'

export default {
  components: { ComponentA, ComponentB },
  data() {
    return {
      currentComponent: 'ComponentA'
    }
  }
}
</script>

  • 切换组件时,被缓存的组件不会触发 beforeDestroydestroyed 等销毁钩子,再次显示时也不会重新触发 createdmounted 等初始化钩子。
2. 缓存路由组件

在路由切换场景中(如标签页),缓存页面组件:

vue

<!-- App.vue 中 -->
<template>
  <div>
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    
    <!-- 缓存路由组件 -->
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

  • 路由切换时,被缓存的页面组件状态会保留(如表单输入内容、滚动位置等)。

二、核心属性

<keep-alive> 提供 3 个属性控制缓存范围:

属性类型说明
include字符串 / 正则仅缓存名称匹配的组件(需匹配组件的 name 选项)
exclude字符串 / 正则不缓存名称匹配的组件(优先级高于 include
max数字 / 字符串最多缓存的组件实例数量,超出时销毁最早缓存的实例(避免内存占用过高)
1. include 与 exclude(匹配组件名称)

需确保组件定义了 name 选项(单文件组件默认以文件名作为 name,但显式定义更可靠):

vue

<!-- 组件 A(ComponentA.vue) -->
<script>
export default {
  name: 'ComponentA' // 必须定义 name 才能被 include/exclude 匹配
}
</script>

使用示例:

vue

<!-- 仅缓存 ComponentA 和 ComponentB -->
<keep-alive include="ComponentA,ComponentB">
  <component :is="currentComponent"></component>
</keep-alive>

<!-- 不缓存 ComponentC -->
<keep-alive exclude="ComponentC">
  <router-view></router-view>
</keep-alive>

<!-- 正则匹配(需用 v-bind) -->
<keep-alive :include="/Component[A|B]/">
  <component :is="currentComponent"></component>
</keep-alive>
2. max 限制缓存数量

vue

<!-- 最多缓存 3 个组件实例 -->
<keep-alive max="3">
  <router-view></router-view>
</keep-alive>

  • 当缓存的组件实例超过 3 个时,最早被缓存的实例会被销毁(触发 deactivated 钩子)。

三、缓存组件的生命周期钩子

被 <keep-alive> 缓存的组件,会新增两个专属钩子:

钩子触发时机用途示例
activated组件从缓存中被激活(显示)时触发刷新数据、重置定时器等
deactivated组件被缓存(隐藏)时触发清除定时器、保存临时状态等

示例:

vue

<!-- 缓存的组件中 -->
<script>
export default {
  activated() {
    // 组件显示时执行(如重新请求数据)
    this.fetchData()
    this.timer = setInterval(() => {}, 1000)
  },
  deactivated() {
    // 组件隐藏时执行(如清除定时器)
    clearInterval(this.timer)
  },
  // 注意:created/mounted 仅在组件首次创建时执行一次
  mounted() {
    console.log('仅执行一次')
  }
}
</script>

四、结合路由的高级用法

实际开发中,常需要 “按需缓存路由组件”(部分页面缓存,部分不缓存),可通过 路由元信息(meta) 实现:

1. 路由配置中标记是否需要缓存

js

// router/index.js
const routes = [
  {
    path: '/home',
    component: Home,
    meta: { keepAlive: true } // 需要缓存
  },
  {
    path: '/about',
    component: About,
    meta: { keepAlive: false } // 不需要缓存
  }
]
2. 在 router-view 中根据元信息动态控制

vue

<template>
  <!-- 动态决定是否缓存当前路由组件 -->
  <keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>
</template>

五、注意事项

  1. 仅缓存组件实例,不缓存 DOM
    <keep-alive> 缓存的是组件实例(数据和状态),DOM 会被复用,但不会 “冻结” DOM 状态(如 v-show 控制的显示状态会被保留,因为依赖数据)。

  2. 不支持缓存函数式组件
    函数式组件没有实例,无法被缓存,需改用状态式组件。

  3. 避免过度缓存
    缓存过多组件会占用内存,尤其是包含大量数据的组件,建议结合 max 属性限制数量。

  4. Vue3 中的变化
    Vue3 中 <keep-alive> 的用法与 Vue2 一致,但需注意:

    • 组件的 name 选项在 <script setup> 中需显式定义(defineOptions({ name: 'XXX' }))。
    • 配合 <Suspense> 使用时,缓存逻辑会作用于异步组件的加载状态。

总结

<keep-alive> 是优化组件切换性能的关键工具,核心价值在于保留组件状态、减少重复渲染。实际使用时需结合 include/exclude 精准控制缓存范围,通过 activated/deactivated 处理缓存前后的逻辑,并注意避免无差别缓存导致的内存问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值