AST与虚拟 DOM(VNode)
在Vue的渲染流程中,AST(抽象语法树)和虚拟DOM(Virtual DOM,简称VNode)是两个不同阶段的核心概念,它们既相互区别又紧密关联,共同支撑了Vue的模板编译与视图渲染机制。
1. 概念与作用
- 
AST(抽象语法树)
AST是编译阶段的产物,用于描述模板的静态结构。
当Vue处理模板(如<div>{{ msg }}</div>)时,首先会通过模板解析器将模板字符串解析为AST。AST本质是一个JavaScript对象树,它精确描述了模板中的标签、属性、指令、文本、表达式等语法结构(比如标签名是div,子节点是文本插值{{ msg }})。
作用:作为模板的“结构化表示”,供后续的编译步骤(优化、代码生成)处理。 - 
虚拟DOM(VNode)
虚拟DOM是运行时的产物,用于描述真实DOM的抽象结构。
它是一个轻量的JavaScript对象(如{ tag: 'div', children: [...], props: {} }),包含了真实DOM的关键信息(标签名、属性、子节点等)。
作用:作为真实DOM的“副本”,在数据变化时通过对比新旧VNode的差异(diff算法),计算出最小更新范围,最终只更新必要的真实DOM,避免全量重绘,提升性能。 
2. 两者的核心联系
AST是虚拟DOM的“源头”之一,它们通过渲染函数(render function) 衔接,形成“模板 → AST → 渲染函数 → 虚拟DOM”的完整链路:
- 
模板解析为AST
Vue的模板编译器首先将模板字符串(如<div>{{ msg }}</div>)解析为AST,这一步是对模板语法的结构化分析,不涉及数据动态变化。 - 
AST转换为渲染函数
编译器会对AST进行优化(比如标记静态节点,避免后续重复处理),然后将AST转换为渲染函数(render函数)。
渲染函数是一段JavaScript代码,它的作用是:在运行时根据当前数据,动态生成虚拟DOM。
例如,上述模板对应的渲染函数大致为:function render(h) { return h('div', this.msg); // h函数用于创建VNode } - 
渲染函数生成虚拟DOM
当组件初始化或数据更新时,Vue会执行渲染函数,结合当前数据生成虚拟DOM(VNode树)。
这里的关键是:AST决定了渲染函数的结构,而渲染函数的执行结果就是虚拟DOM。 
3. 本质区别
| 维度 | AST | 虚拟DOM(VNode) | 
|---|---|---|
| 产生阶段 | 编译时(模板解析阶段) | 运行时(数据更新/初始化阶段) | 
| 描述对象 | 模板的静态语法结构 | 真实DOM的抽象(含动态数据) | 
| 核心作用 | 为生成渲染函数提供结构化数据 | 高效计算DOM更新差异 | 
| 是否依赖数据 | 不依赖(纯静态分析) | 依赖(随数据动态变化) | 
总结
AST是模板编译的中间产物,负责将模板的静态结构“翻译”为结构化数据;虚拟DOM是运行时的动态产物,负责描述带数据的DOM结构。两者通过渲染函数关联:AST是渲染函数的“设计图”,而渲染函数执行后生成虚拟DOM,最终驱动真实DOM的更新。
这个流程体现了Vue“编译时优化”与“运行时高效”的结合——通过AST在编译阶段提前处理静态结构,减少运行时虚拟DOM的diff开销,提升性能。
1. React 的流程:JSX → createElement → 虚拟 DOM
React 中开发者通常使用 JSX 编写视图(如 <div>{message}</div>),但 JSX 并非原生 JavaScript 语法,无法被浏览器直接执行。整个过程如下:
- 
第一步:JSX 转译为
createElement调用(涉及 AST)
JSX 需要通过 Babel 等转译工具转换为原生 JavaScript。转译时,Babel 会先将 JSX 解析为 AST(抽象语法树)——这个 AST 是对 JSX 语法结构的描述(比如标签名、属性、子元素、表达式等)。
例如,JSX 代码:<div className="container">Hello {name}</div>会被 Babel 转译为:
React.createElement( 'div', // 标签名 { className: 'container' }, // 属性 'Hello ', // 子节点 name // 动态表达式子节点 )这里的 AST 是 Babel 转译阶段的中间产物,用于将 JSX 语法“翻译”为
React.createElement调用,这个 AST 由转译工具(而非 React 框架自身)处理。 - 
第二步:
React.createElement生成虚拟 DOM
React.createElement是 React 提供的核心 API,它的作用是 直接创建虚拟 DOM 节点(React 中称为 React Element)。
上述createElement调用的返回值是一个 JavaScript 对象(虚拟 DOM),结构大致如下:{ $$typeof: Symbol.for('react.element'), // 标识为 React 元素 type: 'div', // 标签类型 props: { className: 'container', children: ['Hello ', name] }, // 属性和子节点 key: null, ref: null }这个对象就是 React 中的虚拟 DOM,它描述了真实 DOM 的结构(标签、属性、子节点等),且包含了动态数据(如
name)。 
2. 与 Vue 的核心差异:AST 的处理主体不同
- 
Vue 中:AST 是框架内部模板编译器的产物。Vue 会自己解析模板字符串(如
<div>{{ msg }}</div>)生成 AST,再基于 AST 优化并生成渲染函数,最终通过渲染函数生成虚拟 DOM。整个流程(从模板到 AST 再到虚拟 DOM)由 Vue 框架自身完成。 - 
React 中:AST 是外部转译工具(如 Babel)处理 JSX 时的中间产物。React 框架本身不负责解析 JSX 生成 AST,而是依赖转译工具将 JSX 转换为
createElement调用,再通过这个 API 直接生成虚拟 DOM。AST 的处理与 React 框架本身是解耦的。 
3. 总结
React.createElement的直接作用是生成虚拟 DOM(React Element),而非处理 AST。- AST 在 React 流程中是 JSX 转译为 
createElement调用的中间产物,由 Babel 等工具生成,用于解析 JSX 的语法结构。 - 相比 Vue 自处理模板→AST→渲染函数的全流程,React 更依赖 JSX 转译工具与 
createElement的配合,将语法解析与虚拟 DOM 生成解耦,这也是两者设计理念的重要差异。 
本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/19061688

                
            
        
浙公网安备 33010602011771号