vnode树由render函数逐层构造,是可计算、可对比的轻量级dom描述;其层级依赖children嵌套与shapeflag标识,parent字段仅创建时注入且不保证同步更新,真实dom映射通过elm字段在patch后单向绑定。

Vue 的 VNode 树不是自动“长出来”的,而是在 render 过程中由渲染函数逐层构造出来的结构。它反映真实 DOM 的嵌套逻辑,但不等于真实 DOM 的镜像副本——它是可计算、可对比、可复用的轻量级描述。
树状结构由 render 函数显式构建
VNode 树的根节点通常来自组件的 render 函数返回值,子节点通过 children 数组嵌套组织。每个子 VNode 都是一个独立对象,内部不含“父引用”的自动推导逻辑;它的 parent 字段是在调用 h() 创建时,由当前渲染上下文(如 currentInstance)主动注入的。
- 手动在 setup 或非 render 环境中调用 h(),parent 可能为 null
- children 数组只存子节点引用,不反向维护 parent 关系
- 移动节点(如 v-for 中 key 变化)时,patch 阶段不会自动更新 parent 字段
层级关系依赖类型与 shapeFlag 标识
VNode 的层级语义不仅靠嵌套,还靠 shapeFlag 和 tag 共同定义。比如:
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
- 元素 VNode(shapeFlag & 1):tag 是字符串('div'、'ul'),children 是子 VNode 或文本节点数组
- 组件 VNode(shapeFlag & 4):tag 是组件定义对象,其 children 是插槽内容,实际 DOM 结构在子组件内部生成
- 文本 VNode:text 字段有值,tag 为 null,不能有 children
- 注释/空 VNode:无真实 DOM 对应,仅用于占位或条件控制
父子引用不是运行时可靠依据
虽然 VNode 对象上有 parent 属性,但它仅在创建时设置一次,且 patch 过程中不保证同步更新。因此:
- 不应在组件逻辑中依赖 vnode.parent 判断归属或触发副作用
- 跨组件通信、状态定位应走 props / emits / provide / inject 等 Vue 原生机制
- 调试时可打印 vnode.parent 查看初始结构,但不可用于生产判断
真实 DOM 映射是单向、延迟绑定的
VNode 树本身不持有真实 DOM,只有在首次挂载或 patch 后,才通过 elm 字段指向对应的真实节点。这个绑定发生在:
- 首次 mount:递归遍历 VNode 树,创建并插入真实 DOM,同时赋值 elm
- 后续 patch:对比新旧 VNode,复用或替换真实 DOM,elm 字段随之更新或清空
- 卸载时:elm 保留但不再有效,需手动清理事件或定时器等副作用









