最直接有效的方式是在自定义渲染器平台方法中加入日志输出或断点调试,显性化 patch 每一步动作;通过 createElement、patchProp、insert 等方法注入 console.log,配合 [+] [→] [−] 标记操作类型,并用状态栏实时展示 vnode 路径与更新行为。

最直接有效的方式,是在自定义渲染器的平台操作方法中加入日志输出或断点调试,把 patch 的每一步“动作”显性化。它不依赖 DevTools 插件或第三方库,而是从 Vue 渲染链路最底层切入,让 diff 和更新过程真正可观察、可追踪。
在关键平台方法中注入日志
Vue 的 createRenderer 接收一个配置对象,其中每个方法都对应真实 DOM 操作的一个环节。只要在这些方法里加 console.log,就能看到 patch 如何一步步推进:
-
createElement:打印“创建 ”“创建
”,确认节点生成顺序
- patchProp:区分事件(
onClick → click)和属性(id="app"),记录增删改动作- insert:显示“将 插入到
”,反映挂载位置与锚点逻辑- remove 和 unmount:标记哪些节点被卸载,验证 key 复用是否生效
- setElementText 和 setText:对比前后文本值,直观看到最小更新粒度(如只改一个词,而非重绘整段)
用颜色/符号标记 Diff 类型
单纯文字日志易混淆,可增强可读性:
- 用 [+] 创建、[→] 更新、[−] 卸载 区分操作类型
- 对事件绑定加前缀 [EVENT],如 [EVENT] 绑定 click
- 对复用节点加标识 [REUSE],例如 “[REUSE] 复用旧
- 节点”
配合简单 UI 实时展示 Patch 路径
可在页面顶部加一个状态栏,动态显示当前正在 patch 的 vnode 路径(如
/app/div[0]/ul/li[2])和操作类型:- 利用
vnode.key或vnode.type构建简易路径(无需完整 keypath,够定位即可) - 在
processElement或patch主函数入口处更新该状态栏 - 添加清空按钮和计数器,统计本次更新共执行多少次 insert/remove/setText
构造对比案例验证 Diff 行为
设计几组典型场景,手动触发两次 render,观察日志差异:
-
文本更新:
<span>Hello</span> → <span>Hi</span>→ 应只触发setText,无 create/insert -
列表增删:
[A,B,C] → [A,X,C]→ 应复用 A/C,卸载 B,插入 X(若无 key 则全量替换) -
事件变更:
@click="a" → @click="b"→ 应先 remove click,再 add click -
组件更新:子组件 props 变化 → 触发其内部
patch,但父组件元素本身不重建
不复杂但容易忽略——真正的 patch 过程就藏在这些平台方法的调用链条里。你不需要读懂整个 runtime-core,只需盯住自己写的那十几行 renderer 配置,就能看清 Vue 是如何“聪明地”更新页面的。
- patchProp:区分事件(










