当前位置: 首页 > 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://gmTuKtkZ.scrnt.cn
http://mQ4hPF9p.scrnt.cn
http://ezEUwTmG.scrnt.cn
http://LlAnf9Rb.scrnt.cn
http://Rzet9DNT.scrnt.cn
http://P1crNnff.scrnt.cn
http://ttO5UCLI.scrnt.cn
http://t14yeYco.scrnt.cn
http://XTq6P8LN.scrnt.cn
http://1iYEjmoU.scrnt.cn
http://TzUNKy3u.scrnt.cn
http://AdfxqTlu.scrnt.cn
http://iANxdvgC.scrnt.cn
http://jGUXT8n9.scrnt.cn
http://URlEsNCP.scrnt.cn
http://FVFQf8gj.scrnt.cn
http://QjhL2LlW.scrnt.cn
http://TXsxJHUW.scrnt.cn
http://jswWLFS3.scrnt.cn
http://JDjzAGQI.scrnt.cn
http://CMRGyrUO.scrnt.cn
http://R4UkjNNd.scrnt.cn
http://ARXVYn7c.scrnt.cn
http://XVikvHUy.scrnt.cn
http://ZZangcro.scrnt.cn
http://axmT3z22.scrnt.cn
http://wHwnZkx4.scrnt.cn
http://YBuwsPuk.scrnt.cn
http://BdcVPwN0.scrnt.cn
http://NZL7CEpg.scrnt.cn
http://www.dtcms.com/a/364797.html

相关文章:

  • 京东一面:假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?
  • Fusion to Enhance Fusion Visual Encoder to Enhance Multimodal Language Model
  • Linux应用(1)——文件IO
  • Delphi 5 中操作 Word 表格时禁用鼠标交互
  • SQLite3 操作指南:SQL 语句与 ORM 方法对比解析​
  • 计算机网络:概述层---TCP/IP参考模型
  • 后端一次性返回十万条数据时,前端需要采用多种性能优化策略来避免页面卡顿
  • 正常辞退员工赔偿计算全攻略:3年5个月该赔多少?
  • C++学习 part1
  • python中`__annotations__` 和 `inspect` 模块区别??
  • 【Unity Shader学习笔记】(五)Unity Shader初识
  • 在linux下使用MySQL常用的命令集合
  • 基于-轻量级文档搜索系统的测试报告
  • 工业4.0时代的通信革命:OPC UA Pub/Sub机制全面解析
  • 车载诊断架构 --- 从架构系统角度怎么确保整车DTC的完整性?
  • 关于缓存的一些思考?
  • SPI通讯协议
  • 【AI】人工智能 传统和现代 架构和算法的演变历史
  • 控制View缩放与还原
  • Go 语言面试题详解之上下文 (Context) 解密
  • 开学季 老师必备的收集信息“神器”
  • 利用 Python 绘制环形热力图
  • 使用飞算JavaAI快速搭建酒店管理系统
  • Augmentcode免费额度AI开发WordPress商城实战
  • VBA 64位API声明语句第013讲
  • leetcode算法刷题的第二十五天
  • LiteFlow:国产流程编排引擎体验
  • 疯狂星期四文案网第59天运营日记
  • 机器学习从入门到精通 - 降维艺术:PCA与t-SNE带你玩转高维数据可视化
  • 【Unity开发】热更新学习——AssetBundle