vue缓存实现原理
Vue 缓存实现原理
Vue 中的缓存主要通过 keep-alive 组件实现,用于缓存动态组件或路由组件,避免重复渲染和销毁,提升性能。
keep-alive 的核心机制
keep-alive 是一个抽象组件,不会渲染成 DOM 元素。它通过 include、exclude 和 max 属性控制哪些组件需要缓存。

- 缓存策略:
keep-alive内部维护一个缓存对象cache,以组件的name或tag作为键,存储组件的 VNode(虚拟节点)。 - 生命周期钩子:被缓存的组件会触发
activated和deactivated钩子,而非created和destroyed。 - LRU 算法:当缓存数量超过
max时,keep-alive会使用 LRU(最近最少使用)策略淘汰最久未使用的组件。
实现缓存的关键代码
Vue 源码中 keep-alive 的核心逻辑如下:

// 简化版源码
export default {
name: 'keep-alive',
abstract: true, // 标记为抽象组件
props: {
include: [String, RegExp, Array],
exclude: [String, RegExp, Array],
max: [String, Number]
},
created() {
this.cache = Object.create(null) // 缓存对象
this.keys = [] // 缓存键集合(用于 LRU)
},
destroyed() {
for (const key in this.cache) {
pruneCacheEntry(this.cache, key, this.keys)
}
},
render() {
const slot = this.$slots.default
const vnode = getFirstComponentChild(slot) // 获取第一个子组件
const componentOptions = vnode && vnode.componentOptions
if (componentOptions) {
const name = getComponentName(componentOptions)
const { include, exclude } = this
// 检查是否需要缓存
if (
(include && (!name || !matches(include, name))) ||
(exclude && name && matches(exclude, name))
) {
return vnode
}
const { cache, keys } = this
const key = vnode.key == null
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
: vnode.key
// 命中缓存时直接返回缓存的 VNode
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
remove(keys, key)
keys.push(key) // 更新 LRU 顺序
} else {
cache[key] = vnode
keys.push(key)
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true // 标记为已缓存
}
return vnode || (slot && slot[0])
}
}
缓存的实际应用场景
-
路由切换优化:结合 Vue Router 缓存页面组件,避免重复加载数据。
<keep-alive> <router-view></router-view> </keep-alive> -
动态组件切换:缓存频繁切换的组件(如 Tab 栏内容)。
<keep-alive :include="['ComponentA', 'ComponentB']"> <component :is="currentComponent"></component> </keep-alive>
注意事项
- 组件必须命名:被缓存的组件需通过
name选项声明名称,否则include/exclude无法生效。 - 数据更新问题:缓存的组件不会触发
mounted,需通过activated钩子或监听路由参数更新数据。 - 内存管理:大量缓存可能导致内存占用过高,需合理设置
max属性。






