vue keepalive 实现原理
Vue KeepAlive 实现原理
Vue 的 KeepAlive 是一个内置组件,用于缓存不活动的组件实例,避免重复渲染和销毁,从而提升性能。其核心原理基于组件的生命周期钩子和虚拟 DOM 的缓存机制。
缓存机制
KeepAlive 通过 cache 对象存储被缓存的组件实例。每个缓存的组件实例通过唯一的 key 标识(通常是组件的 name 选项或路由的 key)。当组件切换时,KeepAlive 会检查 cache 中是否存在对应的实例,决定是否复用或销毁。
生命周期钩子
被 KeepAlive 包裹的组件会触发特定的生命周期钩子:
- activated:当组件从缓存中重新激活时调用。
- deactivated:当组件被缓存时调用。
这些钩子允许开发者在组件被缓存或激活时执行特定逻辑,例如数据刷新或动画效果。
虚拟 DOM 与渲染
KeepAlive 通过 render 函数实现缓存逻辑。在渲染过程中,它会根据当前的 include、exclude 和 max 属性决定是否缓存组件:
- include:只有匹配的组件会被缓存。
- exclude:匹配的组件不会被缓存。
- max:限制最大缓存实例数,超出时会销毁最久未使用的实例(LRU 算法)。
源码核心逻辑
以下是简化后的 KeepAlive 核心逻辑(基于 Vue 3 源码):
const KeepAlive = {
__isKeepAlive: true,
props: {
include: [String, RegExp, Array],
exclude: [String, RegExp, Array],
max: [String, Number]
},
setup(props, { slots }) {
const cache = new Map();
const keys = new Set();
let pendingCacheKey = null;
const pruneCacheEntry = (key) => {
const cached = cache.get(key);
if (cached) {
cache.delete(key);
keys.delete(key);
}
};
watch(() => [props.include, props.exclude], () => {
for (const key of cache.keys()) {
if (!matches(key)) pruneCacheEntry(key);
}
});
return () => {
const children = slots.default();
const rawVNode = children[0];
const key = getKey(rawVNode);
pendingCacheKey = key;
if (cache.has(key)) {
rawVNode.component = cache.get(key).component;
} else {
cache.set(key, rawVNode);
keys.add(key);
if (props.max && keys.size > props.max) {
pruneCacheEntry(keys.values().next().value);
}
}
return rawVNode;
};
}
};
使用场景与注意事项
- 路由切换:结合 Vue Router 缓存页面组件,避免重复加载数据。
- 动态组件:通过
component :is切换组件时保留状态。 - 性能优化:对复杂组件或频繁切换的组件使用缓存。
注意事项:

- 缓存的组件会占用内存,需合理设置
max。 - 避免缓存过多实例,可能导致内存泄漏。
- 动态路由需确保
key的唯一性(如结合路由参数)。






