处理KeepAlive 内部原理大揭秘:VNode 缓存与真实 DOM 挂载的关系解析这类问题时,先确认目标场景,再按步骤核对配置或玩法细节。
KeepAlive 的核心是缓存 VNode 并复用其关联的真实 DOM,而非缓存组件实例;它保留 VNode 及其 el 引用的 DOM 节点,激活时直接重挂 DOM、跳过 mount,响应式状态与事件监听器均保持原样。
KeepAlive 的核心不是“缓存组件实例”,而是“缓存 VNode 并复用其关联的真实 DOM”。它不重新创建组件、不重复执行 setup 或 created,也不触发 mounted;关键在于把已卸载的 VNode 及其挂载后的 DOM 节点一并保留在内存中,下次激活时直接恢复显示。
KeepAlive 包裹的组件在首次渲染后,会生成一个对应的 VNode(虚拟节点),这个 VNode 持有对真实 DOM 元素的引用(el 属性)。当组件被切换出去(比如路由跳转或 v-if 为 false),Vue 不会销毁该 VNode,而是将其存入 cache Map 中,并将对应的真实 DOM 从页面中 detach(移除但不 destroy)——DOM 节点依然存在内存里,只是脱离了 document 流。
当 KeepAlive 再次激活该组件(如路由返回、v-if 变回 true),它不会调用 mount(),而是:
这个过程绕过了整个标准挂载流水线(createApp → render → patch → mount),所以极快——本质是 DOM 节点的“热插拔”。
浏览器垃圾回收(GC)只清理“不可达对象”。KeepAlive 的 cache Map 强引用着 VNode,而 VNode 的 el 属性又强引用着真实 DOM 元素及其子树(包括绑定的事件处理器、自定义属性、__vue_app__ 等)。只要 cache 不清空,这些 DOM 就不会被释放。
这些 props 不影响渲染逻辑,只干预缓存策略:
max 达到时的淘汰动作是同步的:VNode 从 cache 删除 → el 被 hostRemove → 组件 instance 触发 unmounted → 响应式依赖被 cleanup → DOM 可被 GC。