二次元绘画创作
56.21M · 2026-02-04
在后台管理系统或长列表页面中,我们经常遇到这样的需求:从列表进入详情页,返回时希望列表滚动位置、搜索条件都能完美保留。Vue 内置的 <KeepAlive> 正是为此而生。本文将带你从基础用法出发,直击其背后的缓存算法原理。
<KeepAlive> 是一个内置组件,用于缓存不活动的组件实例,而不是销毁它们。
在 Vue 中,我们通常结合路由的 meta 字段和 <router-view> 的插槽语法来实现。
// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/your-path',
name: 'YourComponentName',
component: () => import('./views/YourComponent.vue'),
meta: {
keepAlive: true // 设置需要缓存
}
}
];
在 App.vue 或主布局文件中,接着在对应<router-view>的中插入<keep-alive>,并设置include属性来匹配需要缓存的组件
代码段
// includeComponents为对应的组件文件名称
<router-view v-slot="{ Component }">
<KeepAlive :include="includeComponents">
<component :is="Component" />
</KeepAlive>
</router-view>
一旦组件被缓存,其正常的销毁流程将被“冻结”,取而代之的是两个专属钩子:
activated:组件被激活(初始化渲染或从缓存中恢复)时调用。此时可重新获取数据或重置滚动位置。deactivated:组件被停用(离开当前路由)时调用。此时可清理定时器或取消未完成的请求。<KeepAlive> 本质上是一个“无渲染组件”,它不渲染多余的 DOM,而是直接操作组件的 VNode。
Keep-Alive 内部维护了一个 cache 对象(Map 结构)和一个 keys 队列(Array 结构):
key,值是组件的 vnode 实例。当 render 函数执行时:
cache 中是否存在该组件的实例。keys 队列中的位置(移到最后)。如果缓存的组件过多,内存会爆炸吗?不会。 Vue 使用了 LRU (Least Recently Used) 最近最少使用 算法。当缓存数量超过 max 属性设定的阈值时,Vue 会自动销毁 keys 队列中最久没被访问过的那个组件实例。
include 匹配的是组件定义的 name 选项。在 Vue 3 <script setup> 中,如果你没有显式定义 name,Vue 会根据文件名自动生成,建议显式定义以防匹配失效。<router-view> 层级很深,每一层都需要配置 <KeepAlive> 才能保证整条路径上的状态都被保留。<component :is> 上绑定正确的 :key,能有效防止在切换相同组件不同参数(如 /detail/1 到 /detail/2)时出现缓存混乱。