解析Vue源码中是如何进行模版编译的

ops/2024/10/9 10:16:03/

模版编译

联系前文,讲了虚拟DOM的patch过程,而虚拟DOM的前提是先有VNode,那么VNode又是从哪里来的?接下来讲的模版编译便是:把用户写的模版进行编译,就会产生VNode。

在日常开发中,我们把写在<template></template>标签中的类似于原生HTML的内容称之为模版。之所以说是类似于而不是原生html内容是因为在这个标签中不仅写了一些HTML原生内容,还写一些VUE独有的东西,比如v-if,v-for指令,slot插槽等,这些是原生中所没有的,不能被接受的,但实际上我们确实这样写了,也正确显示了,这就是因为Vue有模版编译功能,它会将template里面的所有内容进行编译,把原生HTML找出来解析,再把非原生内容找出经过一系列处理生成渲染函数,也就是render函数,而render函数会将模版生成对应的VNode,而VNode再经过之前介绍的patch过程从而得到将要渲染的视图的VNode,创建真实DOM节点,完成视图更新。

1.渲染流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.模版编译流程
2.1.抽象语法树AST

用户在template中写的模版对于Vue来说就是一堆字符串,那么如何解析这一堆字符串并且从中提取出元素的各个属性呢?这就需要一个叫做抽象语法树的东西。

Abstract Syntax Tree , AST抽象语法树,是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说是抽象的,是因为这里的语法并不会表示出真实语法中出现的每个细节。

比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。——来自百度百科

这里推荐一个网站

https://astexplorer.net/

这里可以转换html标签成为一个JS对象

2.2 具体流程

将一堆字符串模版解析成抽象语法树AST后,我们就可以对其进行各种操作了,处理完后用处理后的AST来生成render函数,其具体流程可以大致分为三个阶段:

1.模版解析阶段:用正则表达式等方法解析为AST

2.优化阶段:遍历AST,将静态节点标记

3.代码生成阶段:将AST转换为渲染函数

这三个阶段在源码中对应三个模块:

  1. 模板解析阶段——解析器——源码路径:src/compiler/parser/index.js;
  2. 优化阶段——优化器——源码路径:src/compiler/optimizer.js;
  3. 代码生成阶段——代码生成器——源码路径:src/compiler/codegen/index.js;

对应源码如下:

javascript">// 源码位置: /src/complier/index.jsexport const createCompiler = createCompilerCreator(function baseCompile (template: string,options: CompilerOptions
): CompiledResult {// 模板解析阶段:用正则等方式解析 template 模板中的指令、class、style等数据,形成ASTconst ast = parse(template.trim(), options)if (options.optimize !== false) {// 优化阶段:遍历AST,找出其中的静态节点,并打上标记;optimize(ast, options)}// 代码生成阶段:将AST转换成渲染函数;const code = generate(ast, options)return {ast,render: code.render,staticRenderFns: code.staticRenderFns}
})
  • const ast =parse(template.trim(), options):parse 会用正则等方式解析 template 模板中的指令、classstyle等数据,形成AST
  • optimize(ast, options): optimize 的主要作用是标记静态节点,这是 Vue 在编译过程中的一处优化,挡在进行patch 的过程中, DOM-Diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能。
  • const code =generate(ast, options): 将 AST 转化成 render函数字符串的过程,得到结果是 render函数 的字符串以及 staticRenderFns 字符串。

最终baseCompile的返回值:

javascript">{ast: ast,render: code.render,staticRenderFns: code.staticRenderFns}

code是一个对象


http://www.ppmy.cn/ops/123127.html

相关文章

python 实现graph list图列算法

graph list图列算法介绍 图列&#xff08;Graph List&#xff09;算法通常指的是在图的表示中&#xff0c;使用列表&#xff08;List&#xff09;或更具体地说&#xff0c;邻接表&#xff08;Adjacency List&#xff09;来表示图的一种算法。邻接表是图的一种常见表示方法&…

STM32-HAL库 驱动DS18B20温度传感器 -- 2024.10.8

目录 一、教程简介 二、驱动理论讲解 三、CubeMX生成底层代码 四、Keil5编写代码 五、实验结果 一、教程简介 本教程面向初学者&#xff0c;只介绍DS18B20的常用功能&#xff0c;但也能满足大部分的运用需求。跟着本教程操作&#xff0c;可在10分钟内解决DS18b20通信难题。…

ISO IEC 18004 2015 PDF 文字版下载

ISO_IEC_18004_2015_en-US - 道客巴巴 (doc88.com)https://www.doc88.com/p-67816330893254.html

PostgreSQL常用字符串函数

PostgreSQL 提供了丰富的字符串函数&#xff0c;可以对字符串进行操作、处理和格式化。以下是一些常用的字符串函数及其示例&#xff1a; 1. LENGTH() - 计算字符串的长度 SELECT LENGTH(Hello World); -- 返回 112. CONCAT() - 拼接字符串 将多个字符串连接在一起。 SELE…

CloudStack计算节点配置

主机信息 CloudStack计算节点 任务1、计算节点基础环境准备 1)需要创建2张网卡&#xff01;&#xff01;&#xff01;】 2)VMware Workstation 中设置网卡模式为NAT&#xff0c;在“网络编辑器”中设置DHCP&#xff0c;网关设置为192.168.100.1&#xff0c;地址段为192.168.…

数据分析 | 标准化与归一化

标准化和归一化是两种常见的数据预处理技术&#xff0c;用于将数值特征转换到相同的尺度上&#xff0c;以提高机器学习模型的性能。以下是对这两种技术 的详细解释及Python代码示例。 1. 标准化&#xff08;Standardization&#xff09; 定义&#xff1a; 标准化是将数据特征…

016 规格参数

文章目录 新增AttrController.javaAttrVo.javaAttrServiceImpl.javaAttrAttrgroupRelationEntity.javaAttrEntity.javaAttrGroupEntity.java 查询AttrController.javaAttrServiceImpl.javaAttrRespVo.java 修改回显AttrController.javaAttrServiceImpl.java 修改提交AttrContro…

代码随想录算法训练营Day29 | 93.复原IP地址、78.子集、90.子集Ⅱ

目录 93.复原IP地址 78.子集 90.子集Ⅱ 93.复原IP地址 题目 93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔…