在Vue 3中,<keep-alive>
组件用于缓存动态组件或路由组件的状态,避免重复渲染,提升性能。
我们新建两个组件,在每一个组件里面写一个input,在默认情况下当组件切换的时候,数据会被清空,但是我们用keep-alive包起来之后,数据将会被缓存,切换的时候不会被清空
html
<template>
<div>
<button @click="flag = !flag">Change</button>
<keep-alive>
<A v-if="flag" />
<B v-else />
</keep-alive>
</div>
</template>
<script setup lang='ts'>
import { ref } from 'vue'
import A from './components/A.vue'
import B from './components/B.vue'
const flag = ref<boolean>(true)
</script>
<style scoped>
</style>
属性配置
1. include
& exclude
include : 声明想要被缓存的组件,比如我们有两个组件,我们只想缓存A组件,不想缓存B组件,那么我们可以用include声明,include支持字符串,数组,正则,比如:这个时候,当我们切换组件的时候,B组件是没有被缓存的
exclude : 和include作用相反,exclude是声明不想被缓存的组件
html
<keep-alive :include="['Home', 'About']" :exclude="['Contact']">
<component :is="currentComponent" />
</keep-alive>
组件名要求 :组件需显式定义name
选项。使用<script setup>
时,可通过以下方式定义
javascript
<script>
export default { name: 'Home' } // 单独定义name
</script>
<script setup>
// 组件逻辑
</script>
2. max
限制最大缓存实例数,超出时销毁最久未访问的实例:
html
<keep-alive max="5">
<component :is="currentComponent" />
</keep-alive>
生命周期钩子
被缓存的组件会触发特定生命周期:
-
activated
:组件被激活时触发。 -
deactivated
:组件被切出缓存时触发。
在组合式API中使用:
javascript
<script setup>
import { onActivated, onDeactivated } from 'vue';
onActivated(() => {
console.log('组件激活,可刷新数据');
});
onDeactivated(() => {
console.log('组件离开,清理操作');
});
</script>
结合Vue Router
-
按路由元信息缓存
通过路由的
meta
字段控制缓存:html<router-view v-slot="{ Component }"> <keep-alive> <component :is="Component" v-if="$route.meta.keepAlive" /> </keep-alive> <component :is="Component" v-if="!$route.meta.keepAlive" /> </router-view>
路由配置:
javascriptconst routes = [ { path: '/home', component: Home, meta: { keepAlive: true } }, { path: '/about', component: About } ];
-
动态路由参数处理
添加唯一
key
确保不同参数实例独立缓存:html<keep-alive> <component :is="Component" :key="$route.fullPath" /> </keep-alive>
注意事项
-
组件命名 :确保缓存的组件已正确设置
name
。 -
内存管理 :使用
max
限制缓存数量,避免内存过度占用。 -
数据刷新 :在
activated
中更新数据,而非mounted
。 -
嵌套组件 :
<keep-alive>
仅缓存直接子组件。
示例场景
html
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="cachedComponents" :max="3">
<component
:is="Component"
:key="$route.fullPath"
v-if="$route.meta.keepAlive"
/>
</keep-alive>
<component
:is="Component"
:key="$route.fullPath"
v-if="!$route.meta.keepAlive"
/>
</router-view>
</template>
<script setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const cachedComponents = computed(() =>
route.matched
.filter(r => r.meta.keepAlive)
.map(r => r.components.default.name)
);
</script>
通过合理配置<keep-alive>
,可以有效优化应用性能,同时结合路由和组件生命周期管理数据状态。