vnode 是 vue 渲染系统的中间语言,即描述页面结构与状态的轻量、不可变 javascript 对象;它通过 tag、props、children、key、shapeflag 等字段声明式定义节点类型与关系,经模板→ast→渲染函数→vnode→dom 四步转化,支撑跨平台、精准 diff、可干预渲染及静态优化。

VNode 是 Vue 渲染系统真正的“中间语言”——它不渲染、不绑定事件、不操作 DOM,却承载了所有关于“页面该长什么样”的结构与状态信息。理解 VNode,就是看懂 Vue 如何把模板或 JSX 转成浏览器能画出来的东西。
它不是 DOM,但描述 DOM
VNode 是一个纯 JavaScript 对象,轻量、不可变、无副作用。它不持有真实 DOM 引用(elm 初始为 null),也不执行任何 DOM 操作。它的作用只有一个:声明式地描述节点的类型、属性和嵌套关系。
-
tag:可以是字符串(
"div")、组件构造函数、Fragment或Teleport等特殊类型 - props(Vue 3)或 data(Vue 2):归一化后的属性集合,含 class/style/事件监听器/on: { click: handler }/指令钩子等
-
children:子节点数组,元素可以是 VNode、字符串(文本)、
null或undefined - key:仅用于 diff 算法识别节点身份,影响复用逻辑,不参与渲染
-
shapeFlag(Vue 3 新增):位标记,快速判断节点类型(如是否为组件、是否带
v-if、是否静态)
从模板到 VNode 的四步转化链
开发者写的模板不会直接变成 DOM,而是经过明确分工的编译流水线:
特色介绍: 1、ASP+XML+XSLT开发,代码、界面、样式全分离,可快速开发 2、支持语言包,支持多模板,ASP文件中无任何HTML or 中文 3、无限级分类,无限级菜单,自由排序 4、自定义版头(用于不规则页面) 5、自动查找无用的上传文件与空目录,并有回收站,可删除、还原、永久删除 6、增强的Cache管理,可单独管理单个Cache 7、以内存和XML做为Cache,兼顾性能与消耗 8、
- 模板字符串 → AST:词法+语法分析,生成结构化的抽象语法树,保留指令、插值、属性等原始信息,但不含运行时逻辑
-
AST → 渲染函数:遍历 AST,生成可执行的 JS 函数代码(如
h('div', { class: this.cls }, [this.text])),缓存后复用 -
渲染函数执行 → VNode 树:组件实例调用
render(),内部调用h()构造根 VNode,并递归生成完整树形结构 -
VNode → 真实 DOM:由平台专属渲染器(renderer)驱动
patch()流程,首次挂载走创建分支,后续更新走 diff + 增量更新
VNode 的类型决定行为逻辑
Vue 不靠 if-else 判断节点用途,而是通过字段组合与类型标识实现差异化处理:
- 普通元素节点:tag 为字符串,data 含 attrs/class/style,children 是子 VNode 数组
- 组件节点:tag 是组件构造函数或异步 Promise,componentOptions 提供 propsData、插槽 children、Ctor 等初始化参数
-
文本节点:tag 为
undefined,text 字段存纯文本,无 data 和 children - 注释/空节点:isComment 或 isStatic 标识,diff 阶段可跳过比对,提升性能
- Fragment/Teleport:type 字段为 Symbol 类型,绕过单根节点限制,支持多根模板与跨容器挂载
为什么必须是 VNode?关键价值在哪
VNode 的存在不是为了炫技,而是解决实际工程问题:
- 跨平台统一接口:同一棵 VNode 树,既可由 Web 渲染器转为真实 DOM,也可由小程序渲染器输出 WXML,还能在 Node.js 中直出 HTML(SSR)
- 可控的更新粒度:响应式触发更新时,只重新执行 render 得到新 VNode 树,diff 算法自动计算最小变更集,避免全量重绘
-
开发者可干预环节:可通过手写 render 函数、使用
h()、或操作 VNode(如封装自定义指令、高阶组件)深入控制渲染逻辑 - 静态节点优化基础:编译阶段标记 isStatic 的节点,在 patch 时直接复用(cloneVNode),减少对象创建开销
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









