渲染器通过VNode挂载/卸载控制生命周期钩子执行:挂载时创建DOM并插入后触发mounted;更新时diff后最小化操作并触发updated;卸载时VNode移出树后移除DOM并触发unmounted;KeepAlive则缓存VNode跳过卸载,仅触发activated/deactivated。

渲染器本身不直接管理组件的生命周期钩子(如 mounted、unmounted),而是通过控制 VNode 的挂载(mount)与卸载(unmount)过程,为这些钩子提供执行时机和上下文。生命周期钩子的触发,本质上是渲染器在关键节点操作中插入的逻辑回调。
挂载时机:VNode 创建后立即关联真实 DOM
当一个新 VNode 首次被渲染到容器中时,渲染器会:
- 调用
createElement创建对应的真实 DOM 元素,并赋值给vnode.el - 将该 DOM 插入父容器(如
container.appendChild(el)) - 在插入完成、且整个子树递归挂载完毕后,触发组件的
mounted钩子(Vue)或componentDidMount(React 类组件) - 对函数组件,
useEffect(() => {}, [])的回调也在此阶段同步执行
更新时机:基于新旧 VNode diff 后的最小化 DOM 操作
当响应式状态变化引发重新渲染时,渲染器执行 patch 流程:
ZenHeart zenlink 与 zenlink-mcp 为 OpenClaw,涵盖安装、MCP 注册、钩子接线、入站轮询及升级维护。
- 对比新旧 VNode 树,识别需要复用、替换、移动或删除的节点
- 仅对发生变化的部分更新真实 DOM(如修改
textContent、切换 class、更新 props) - 不触发挂载/卸载,但会按需调用
updated(Vue)或componentDidUpdate(React) - 若子组件被复用(如 KeepAlive 缓存场景),其 DOM 不重挂,
mounted不重复执行,但activated钩子会被调用
卸载时机:VNode 被移出渲染路径且 DOM 被清除
卸载发生在以下明确条件满足时:
- 该 VNode 在新渲染中不再出现在 VNode 树中(如 v-if 为 false、路由切换、列表过滤)
- 渲染器从父节点中调用
parent.removeChild(vnode.el)移除真实 DOM - 在 DOM 移除前,触发
beforeUnmount(Vue)或componentWillUnmount(React) - DOM 移除后,清理副作用(如定时器、事件监听器、订阅),再触发
unmounted(Vue)或完成卸载流程(React)
KeepAlive 场景下的特殊处理
KeepAlive 不真正卸载 VNode 和其 el,而是:
- 跳过
removeChild,将 VNode 及其vnode.el保留在内存缓存中 - 不触发
unmounted,但会调用deactivated钩子 - 再次激活时,直接将缓存的
vnode.el重新 append 到 DOM,跳过 mount 步骤,只触发activated - 组件实例、响应式状态、事件监听器全部保留,实现“假卸载、真缓存”

















