查看: 103|回复: 1

Vue3动态组件缓存:KeepAlive用法与手动管理实例实践

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
在Vue3项目中,动态组件频繁切换时会重复创建和销毁实例,导致性能损耗。本文通过几个实际案例,演示如何使用KeepAlive内置组件和手动缓存机制来复用组件实例,提升页面响应速度。
  1. // 基础示例:KeepAlive包裹动态组件
  2. <template>
  3.   <div>
  4.     <button @click="current = 'CompA'">显示A</button>
  5.     <button @click="current = 'CompB'">显示B</button>
  6.     <KeepAlive>
  7.       <component :is="current" />
  8.     </KeepAlive>
  9.   </div>
  10. </template>
  11. <script setup>
  12. import { ref } from 'vue'
  13. import CompA from './CompA.vue'
  14. import CompB from './CompB.vue'
  15. const current = ref('CompA')
  16. </script>
复制代码

<KeepAlive>会将切换隐藏的组件保留在内存中,再次显示时无需重新创建,组件内部状态(如输入框内容)也会被保留。

控制缓存范围:include / exclude
若只想缓存特定组件,可使用include属性,其值可以是组件名称字符串、正则或数组。例如只缓存CompA:
  1. <KeepAlive include="CompA">
  2.   <component :is="current" />
  3. </KeepAlive>
复制代码

使用exclude则排除指定组件,其余均被缓存。注意组件名需与注册名称一致(使用<script setup>时默认文件名为组件名)。

限制缓存数量:max属性
当缓存实例过多可能占用内存,max可设置最多缓存实例数,超过时最早缓存的实例会被销毁。
  1. <KeepAlive max="2">
  2.   <component :is="current" />
  3. </KeepAlive>
复制代码

若三个组件轮流切换,只缓存最近两个,第三个出现时第一个被销毁。

生命周期钩子:onActivated / onDeactivated
被KeepAlive缓存的组件会触发两个特殊钩子,可用于数据刷新或资源释放。
  1. // 在CompA.vue中
  2. import { onActivated, onDeactivated } from 'vue'
  3. onActivated(() => {
  4.   console.log('CompA被激活(从缓存显示)')
  5. })
  6. onDeactivated(() => {
  7.   console.log('CompA被停用(隐藏到缓存)')
  8. })
复制代码

手动管理组件实例缓存
某些场景需更灵活的控制,可通过对象手动存储组件实例。利用shallowRef和markRaw避免Vue对组件定义做深层响应式处理。
  1. <template>
  2.   <div>
  3.     <button @click="show('CompA', CompA)">显示A</button>
  4.     <button @click="show('CompB', CompB)">显示B</button>
  5.     <component :is="currentComp" v-if="currentComp" />
  6.   </div>
  7. </template>
  8. <script setup>
  9. import { ref, shallowRef, markRaw } from 'vue'
  10. import CompA from './CompA.vue'
  11. import CompB from './CompB.vue'
  12. const cache = {}
  13. const currentComp = ref(null)
  14. function show(name, comp) {
  15.   if (!cache[name]) {
  16.     cache[name] = markRaw(shallowRef(comp))
  17.   }
  18.   currentComp.value = cache[name].value
  19. }
  20. </script>
复制代码

同样达到复用实例的效果,但需要手动管理缓存对象和显示逻辑。

封装为组合式函数
将手动缓存逻辑抽离成可复用的useDynamicComponent函数:
  1. // useDynamicComponent.js
  2. import { ref, shallowRef, markRaw } from 'vue'
  3. export function useDynamicComponent() {
  4.   const cache = {}
  5.   const currentComp = ref(null)
  6.   const show = (name, component) => {
  7.     if (!cache[name]) {
  8.       cache[name] = markRaw(shallowRef(component))
  9.     }
  10.     currentComp.value = cache[name].value
  11.   }
  12.   return { currentComp, show }
  13. }
  14. </script>
  15. <script setup>
  16. // 使用组合式函数
  17. import { useDynamicComponent } from './useDynamicComponent'
  18. import CompA from './CompA.vue'
  19. import CompB from './CompB.vue'
  20. const { currentComp, show } = useDynamicComponent()
  21. </script>
复制代码

这样多个组件可以共享同一份缓存逻辑,保持代码整洁。

总结
KeepAlive适用于常规动态组件缓存场景,配置简单;手动实例缓存和组合式函数适合需要精细控制或跨组件复用逻辑的情况。根据实际需求选择合适方式,可有效减少不必要的组件销毁重建,提升Vue3应用性能。
回复

使用道具 举报

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

Re: Vue3动态组件缓存:KeepAlive用法与手动管理实例实践

感谢分享!平时用 KeepAlive 比较多,但手动管理实例和组合式函数的思路很实用,尤其是需要精细控制缓存逻辑时,抽成 hook 确实能保持代码干净。请问在手动缓存方案中,如果组件有动态 props 或插槽,你是怎么处理状态同步的呢?
回复 支持 反对

使用道具 举报

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

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

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

官方核心成员

关注微信公众号

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

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

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部