当前位置: 首页 > news >正文

VUE的模版渲染过程

Vue 的模板解析过程是将开发者编写的 HTML 类模板(Template)转换为可执行的 JavaScript 代码(渲染函数)的过程,这是 Vue 响应式系统与视图关联的核心环节。以下是模板解析的完整流程,结合 Vue 3 的实现逻辑展开说明:

一、模板解析的整体目标

将类似 HTML 的模板字符串(如 <div>{{ message }}</div>)转换为 渲染函数(Render Function),最终执行渲染函数生成虚拟 DOM(VNode),再通过虚拟 DOM 映射到真实 DOM。

核心公式:
模板(Template)→ 抽象语法树(AST)→ 优化 AST → 生成渲染函数 → 执行生成 VNode

二、详细解析步骤

1. 模板编译的入口:compile 函数

Vue 提供 compile 函数(或通过单文件组件 SFC 的 <template> 标签触发)作为模板编译的入口,接收模板字符串和编译选项(如 mode: 'module' 或 mode: 'function'),返回渲染函数代码。

示例:

import { compile } from 'vue'const { code } = compile(`<div>{{ message }}</div>`, {mode: 'function' // 生成可直接执行的函数
})
console.log(code) 
// 输出类似:"function render(_ctx, _cache) { ... }"
2. 第一步:解析(Parse)→ 生成抽象语法树(AST)

目标:将模板字符串解析为结构化的 AST(抽象语法树),标记出元素、属性、文本、指令(如 v-ifv-for)、插值(如 {{ }})等节点类型。

具体过程

  • 词法分析(Tokenizer):按字符顺序扫描模板,将字符序列拆分为 “标签开始(<div)”“属性(class="box")”“文本(Hello)”“插值({{ msg }})” 等令牌(Token)
  • 语法分析(Parser):根据 Token 序列构建嵌套的 AST 节点树,每个节点包含:
    • type:节点类型(如 ELEMENTTEXTINTERPOLATION
    • tag:标签名(如 divspan
    • attrs:属性列表(如 [{ name: 'class', value: 'box' }]
    • children:子节点数组
    • 特殊指令标记(如 ifConditions 用于 v-iffor 用于 v-for

示例
模板 <div class="box">{{ message }}</div> 会被解析为:

{type: 1, // ELEMENT 类型tag: 'div',attrsList: [{ name: 'class', value: 'box' }],attrsMap: { class: 'box' },children: [{type: 2, // INTERPOLATION 类型content: {type: 4, // SIMPLE_EXPRESSION 类型content: 'message' // 绑定的变量}}]
}
3. 第二步:优化(Optimize)→ 标记静态节点

目标:遍历 AST,标记出静态节点(内容不会随状态变化的节点),避免在更新时重复渲染,提升性能。

关键逻辑

  • 静态节点:如纯文本节点(<span>静态文本</span>)、无绑定属性的元素(<div class="fixed"></div>),其内容永远不会改变。
  • 静态根节点:包含静态子节点的父节点(但自身不是静态节点),可作为整体跳过更新。

优化后效果
在生成渲染函数时,静态节点会被处理为 “一次性创建” 的代码,后续更新时直接复用,无需重新生成。

4. 第三步:生成(Generate)→ 转换为渲染函数

目标:将优化后的 AST 转换为字符串形式的 JavaScript 渲染函数代码,该函数执行后会返回虚拟 DOM(VNode)。

核心处理

  • 节点转换:根据 AST 节点类型生成对应的 VNode 创建代码:
    • 元素节点 → createElementVNode(tag, props, children)
    • 文本节点 → createTextVNode(text)
    • 插值节点 → toDisplayString(_ctx.message)(结合响应式上下文 _ctx
  • 指令处理:将 v-ifv-forv-bind 等指令转换为条件判断、循环、属性绑定的 JavaScript 逻辑。
    • 例如 v-for="item in list" 会被转换为 _for(_ctx.list, (item) => { ... })
    • v-if="show" 会被转换为 if (_ctx.show) { ... }
  • 缓存处理:对静态节点生成缓存标识(如 _cache),避免重复创建。

示例
模板 <div>{{ message }}</div> 生成的渲染函数大致为:

function render(_ctx, _cache) {return createElementVNode('div',null,[toDisplayString(_ctx.message)] // 插值转换为响应式访问)
}
5. 渲染函数执行 → 生成虚拟 DOM

当组件初始化或响应式数据更新时,Vue 会执行渲染函数,生成虚拟 DOM(VNode)树。VNode 是对真实 DOM 的轻量描述,包含标签名、属性、子节点等信息。

示例 VNode 结构:

{type: 'div',props: null,children: [{ type: Text, children: 'Hello Vue' } // 插值结果]
}
6. 虚拟 DOM 映射为真实 DOM

Vue 的渲染器(Renderer)会对比新旧 VNode 树(diff 算法),计算出最小更新量,最终将差异应用到真实 DOM,完成视图更新。

三、Vue 3 与 Vue 2 模板解析的核心差异

  1. 编译优化:Vue 3 引入 “区块(Block)” 概念,将模板按动态节点分组,diff 时只遍历动态节点,性能大幅提升。
  2. 响应式关联:Vue 3 渲染函数通过 _ctx(组件上下文)访问响应式数据,结合 Proxy 实现更精确的依赖收集。
  3. Tree-shaking:Vue 3 编译产物仅包含模板中使用的 API(如只用到 v-if 则不引入 v-for 相关代码),减小打包体积。

四、总结

Vue 的模板解析是 “声明式模板” 到 “命令式代码” 的转换桥梁,核心流程为:
模板字符串 → 词法/语法分析(AST)→ 静态节点优化 → 生成渲染函数 → 执行生成 VNode → 映射真实 DOM

这一过程隐藏了复杂的 DOM 操作细节,让开发者可以用更直观的 HTML 语法编写视图,同时兼顾性能优化(静态节点缓存、精准更新)。

http://www.xdnf.cn/news/1448857.html

相关文章:

  • FFMPEG H264
  • OpenLayers常用控件 -- 章节一:地图缩放控件详解教程
  • 如何通过level2千档盘口分析挂单意图
  • JavaScript的输出语句
  • 三阶Bezier曲线,已知曲线上一点到曲线起点的距离为L,计算这个点的参数u的方法
  • 专题四_前缀和_一维前缀和
  • 【OC】属性关键字
  • vtk资料整理
  • Linux arm64 PTE contiguous bit
  • linux可以直接用指针操作物理地址吗?
  • torch学习 自用
  • python类的内置属性
  • AI重塑SaaS:从被动工具到智能角色的技术演进路径
  • 【面试题】OOV(未登录词)问题如何解决?
  • Leetcode_202.快乐数_三种方法解决(普通方法解决,哈希表解决,循环链表的性质解决_快慢指针)
  • 简述:普瑞时空数据建库软件(国土变更建库)之一(变更预检查部分规则)
  • PyTorch 中训练语言模型过程
  • 利用 Java 爬虫获取淘宝商品详情 API 接口
  • 嵌入式学习day41-硬件(2)
  • ansible总结2
  • 代码随想录算法训练营第一天 | 704.二分查找 27. 移除元素 977.有序数组的平方
  • python中`__annotations__` 和 `inspect` 模块区别??
  • 两个子进程之间使用命名pipe
  • 从月薪5K到年薪60W!API自动化测试如何让你突破职业瓶颈
  • K8S 部署 NFS Dynamic Provisioning(动态存储供应)
  • 【STM32】STM32F103系列USB大坑 二
  • 具身智能让人形机器人 “活” 起来:懂语言、能感知、会行动,智能进化再提速
  • 使用langgraph创建工作流系列4:人机回环
  • 面试复习题-Flutter
  • 论文介绍:“DUSt3R”,让 3D 视觉从“繁琐”走向“直观”