vue keepalive 实现原理
Vue KeepAlive 实现原理
Vue 的 KeepAlive 是一个内置组件,用于缓存不活动的组件实例,避免重复渲染,提升性能。以下是其核心实现原理:
缓存机制
KeepAlive 通过维护一个缓存对象(cache)存储组件实例。当组件被切换时,KeepAlive 会将不活动的组件实例存入缓存,而非销毁。再次激活时,直接从缓存中恢复实例。
缓存对象的结构为键值对,键是组件的唯一标识(默认基于组件名或匿名组件的 tag),值是组件的 VNode 和实例。

LRU 算法
KeepAlive 默认采用 LRU(最近最少使用)算法管理缓存。当缓存数量超过 max 属性设定的上限时,最久未被访问的实例会被销毁。LRU 通过维护一个访问顺序的链表实现。
生命周期钩子
被 KeepAlive 包裹的组件会触发特定的生命周期钩子:

activated:组件从缓存恢复并插入 DOM 时触发。deactivated:组件被缓存并从 DOM 移除时触发。
VNode 处理
KeepAlive 在渲染阶段通过 render 函数处理子组件:
- 根据
include和exclude属性匹配需要缓存的组件。 - 命中缓存时返回缓存的 VNode,否则渲染新实例并缓存。
源码关键逻辑
以下是简化后的核心逻辑(基于 Vue 3 源码):
const KeepAliveImpl = {
__isKeepAlive: true,
setup(props, { slots }) {
const cache = new Map();
const keys = new Set(); // LRU 顺序维护
return () => {
const children = slots.default();
const rawVNode = children[0];
// 检查是否可缓存
if (!isVNode(rawVNode) || !shouldKeepAlive(rawVNode, props)) {
return rawVNode;
}
const key = rawVNode.key;
const cachedVNode = cache.get(key);
if (cachedVNode) {
// 命中缓存,更新 LRU 顺序
keys.delete(key);
keys.add(key);
return cachedVNode;
} else {
// 未命中,缓存新实例
cache.set(key, rawVNode);
keys.add(key);
// 超出上限时淘汰最旧缓存
if (props.max && keys.size > props.max) {
const oldestKey = keys.values().next().value;
cache.delete(oldestKey);
keys.delete(oldestKey);
}
return rawVNode;
}
};
}
};
使用示例
<template>
<KeepAlive :max="3" include="ComponentA,ComponentB">
<component :is="currentComponent" />
</KeepAlive>
</template>
注意事项
- 动态组件需设置
key以保证缓存正确性。 - 频繁更新的组件可能因缓存占用内存,需合理设置
max。 include和exclude支持字符串、正则或数组格式。






