核心概念
keep-alive
是vue的一个内置组件,用于缓存不活动的组件实例。当切换组件时,它的状态会被保留在内存中,避免重复渲染,提升性能 下面是一个快速了解 keep-alive
的表格:
特性维度 | 说明 |
---|---|
功能 | 缓存非活跃组件实例,避免重复销毁和创建,保持组件状态(如数据、滚动位置) |
核心属性 | include :指定缓存的组件名(字符串、正则、数组) exclude :指定不缓存的组件名 max :最大缓存实例数(采用LRU算法) |
生命周期钩子 | activated :组件被激活(从缓存中恢复)时触发 deactivated :组件被停用(进入缓存)时触发 |
常见应用场景 | 表单页保留用户输入 列表页保持滚动位置和过滤条件 Tab页切换 路由组件缓存(需结合Vue Router) |
注意事项 | 组件需具名(name 选项)以便 include /exclude 匹配 注意及时清理非响应式资源(如定时器、事件监听)防止内存泄漏 合理使用 max 控制缓存量 |
关键原理
keep-alive
通过维护一个缓存对象 (vue2中使用普通对象,vue3使用Map)和一个键数组(vue2使用数组,vue3使用Set)来工作 被包裹的组件切换时,vue会检查名称是否匹配include和exclude,如果匹配缓存条件,组件实例会被存入缓存,否则销毁。当命中缓存时,实例直接从缓存中复用
max属性也很重要,大量缓存会造成内存的压力,设置max,确定最大缓存数量,缓存实例超过上限时,最久未被访问的实例会被销毁
实践应用
基本用法:
- 缓存动态组件 使用component组件配合is属性进行动态切换时,用keep-alive包裹实现缓存
vue
<template>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</template>
- 缓存路由组件 结合vue-router的router-view使用
vue
<template>
<keep-alive>
<router-view></router-view>
</keep-alive>
</template>
- 条件缓存(include/exclude) 精确控制哪些组件需要缓存或不需要缓存。组件必须设置name
vue
<keep-alive :include="['Home', 'About']" :exclude=" /^Temp/" :max="5">
<component :is="currentView"></component>
</keep-alive>
- 在vue router中按路由缓存 meta定义是否需要缓存
js
// router.js (Vue Router 4)
const routes = [
{
path: '/list',
name: 'ListPage',
component: () => import('./ListPage.vue'),
meta: { keepAlive: true } // 需要缓存
},
{
path: '/detail/:id',
name: 'DetailPage',
component: () => import('./DetailPage.vue'),
meta: { keepAlive: false } // 不需要缓存
}
];
在根组件(如 App.vue
)中根据路由的 meta.keepAlive
条件渲染:
vue
<template>
<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>
</template>
keep-alive生命周期变化
- 首次进入组件 :
beforeCreate
->created
->beforeMount
->mounted
->activated
- 再次进入(激活) :
activated
- 离开(失活) :
deactivated
注意 :传统的 mounted
等钩子在首次加载后再次切换回来时不会再次触发 。因此,如果需要数据刷新,应将逻辑放在 activated
钩子中
vue3中是注册onActivated
和 onDeactivated
函数来
vue
<script setup>
import { onActivated, onDeactivated } from 'vue';
onActivated(() => {
// 组件被激活时执行,例如重新请求数据
console.log('Component activated');
});
onDeactivated(() => {
// 组件被缓存时执行,例如清除定时器或取消请求
console.log('Component deactivated');
});
</script>
常见问题
- 组件必须具名
- 合理控制缓存数量
- 及时清理资源
- 何时使用keep-alive
推荐使用 ✅ | 不建议使用 ❌ | 注意事项 |
---|---|---|
表单页跳转后返回需保留数据 | 静态内容展示 | 结合路由 meta 标记 |
长列表滚动位置恢复 | - | 配置路由的滚动行为 |
高频切换的 Tab 页 | - | 设置 max 防内存溢出 |
需要保持组件状态以避免重复渲染和请求的复杂页面 | 组件内容总是实时更新,无需保持状态的页面 | 在 activated 中处理需要更新的逻辑 |
图表
