查看: 102|回复: 1

Vue3 KeepAlive 缓存组件:动态切换与生命周期管理实践

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
在 Vue3 中,KeepAlive 是内置组件之一,用于在多个组件动态切换时缓存被移除的组件实例,避免重复销毁和创建带来的性能损耗。本文将结合实际代码,从基本用法到 include/exclude 控制、最大缓存数、以及 onActivated/onDeactivated 生命周期钩子,全面解析 KeepAlive 的使用细节。

## 一、动态组件与 KeepAlive 基础

Vue3 的 <component> 元素是一个“元组件”,通过 is prop 动态渲染实际组件。默认情况下,每次切换组件时,旧的组件实例会被销毁,新的实例重新创建。使用 KeepAlive 包裹 <component> 后,切换行为变为“休眠/唤醒”,组件的状态(如表单输入、计数器)得以保持。

### 示例:未使用 KeepAlive

父组件 App.vue:
  1. <template>
  2. <div>
  3.   <input type="radio" v-model="activeComponent" :value="A" />
  4.   <label for="A">A</label>
  5.   <input type="radio" v-model="activeComponent" :value="B" />
  6.   <label for="B">B</label>
  7. </div>
  8. <div>Current component:{{ activeComponent.__name }}</div>
  9. <div>
  10.   <component :is="activeComponent" />
  11. </div>
  12. </template>
  13. <script setup>
  14. import { shallowRef, watch } from 'vue';
  15. import A from '@/components/A.vue';
  16. import B from '@/components/B.vue';
  17. const activeComponent = shallowRef(A);
  18. watch(activeComponent, (newVal) => {
  19.   console.log(newVal);
  20. });
  21. </script>
复制代码

子组件 A.vue 维护一个计数,B.vue 维护一个输入框内容。切换时组件状态会丢失。

### 示例:使用 KeepAlive

只需在 <component> 外层包裹 <KeepAlive>:
  1. <KeepAlive>
  2.   <component :is="activeComponent" />
  3. </KeepAlive>
复制代码
此时切换组件,之前的计数和输入内容会被保留。

## 二、包含/排除(include/exclude)

KeepAlive 默认缓存所有内部切换的组件。若只想缓存部分组件,可通过 include 或 exclude prop 定制,匹配规则基于组件的 name 选项。

三种写法:
  1. <!-- 逗号分隔字符串 -->
  2. <KeepAlive include="a,b">
  3.   <component :is="view" />
  4. </KeepAlive>
  5. <!-- 正则表达式 -->
  6. <KeepAlive :include="/a|b/">
  7.   <component :is="view" />
  8. </KeepAlive>
  9. <!-- 数组 -->
  10. <KeepAlive :include="['a', 'b']">
  11.   <component :is="view" />
  12. </KeepAlive>
复制代码

注意:组件必须显式声明 name 选项(在 <script setup> 中可通过文件名自动生成,Vue 3.2.34+ 支持)。

## 三、最大缓存实例数(max)

通过 max prop 限制缓存实例数量,行为类似 LRU 缓存——当超过最大值时,最久未访问的缓存实例会被销毁。
  1. <KeepAlive :max="10">
  2.   <component :is="activeComponent" />
  3. </KeepAlive>
复制代码

## 四、缓存实例的生命周期钩子

被 KeepAlive 缓存的组件不会卸载,而是变为“不活跃”状态。通过 onActivated 和 onDeactivated 可以感知激活/休眠时机:
  1. <script setup>
  2. import { onActivated, onDeactivated } from 'vue'
  3. onActivated(() => {
  4.   // 首次挂载或每次从缓存重新插入时触发
  5. })
  6. onDeactivated(() => {
  7.   // 从 DOM 移除、进入缓存或组件卸载时触发
  8. })
  9. </script>
复制代码

### 嵌套组件的执行顺序

假设 A 组件包含子组件 A1,B 组件包含子组件 B1。切换时,生命周期钩子的执行顺序为“先子后父”且“先休眠后激活”。例如从 A 切换到 B:
- 先执行 A 内部所有子组件的 onDeactivated
- 再执行 A 自身的 onDeactivated
- 然后执行 B 内部所有子组件的 onActivated
- 最后执行 B 自身的 onActivated

代码示例(仅展示关键部分):
  1. // A.vue 与 A1.vue 均注册钩子
  2. // A1.vue
  3. onActivated(() => console.log('A1 onActivated'))
  4. onDeactivated(() => console.log('A1 onDeactivated'))
  5. // A.vue
  6. onActivated(() => console.log('A onActivated'))
  7. onDeactivated(() => console.log('A onDeactivated'))
复制代码

## 总结

KeepAlive 是 Vue3 中优化组件切换性能的核心工具,适用于表单步骤、标签页等场景。通过 include/exclude 精确控制缓存范围,max 避免内存溢出,onActivated/onDeactivated 处理缓存状态下的业务逻辑(如数据刷新)。在实际项目中,建议优先使用 include 明确需要缓存的组件,结合 max 限制缓存数量,避免不必要的内存占用。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Vue3 KeepAlive 缓存组件:动态切换与生命周期管理实践

这篇文章写得很清晰实用,从基础到进阶都覆盖了,尤其是生命周期钩子的执行顺序和嵌套组件的例子,对实际开发很有帮助。感谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-11 23:07 , Processed in 0.046567 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部