Vue源码系列讲解——模板编译篇【一】(综述)

目录

1. 前言

2. 什么是模板编译

3. 整体渲染流程

4. 模板编译内部流程

4.1 抽象语法树AST

4.2 具体流程

5. 总结


1. 前言

在前几篇文章中,我们介绍了Vue中的虚拟DOM以及虚拟DOMpatch(DOM-Diff)过程,而虚拟DOM存在的必要条件是得先有VNode,那么VNode又是从哪儿来的呢?这就是接下来几篇文章要说的模板编译。你可以这么理解:把用户写的模板进行编译,就会产生VNode

2. 什么是模板编译

我们知道,在日常开发中,我们把写在<template></template>标签中的类似于原生HTML的内容称之为模板。这时你可能会问了,为什么说是“类似于原生HTML的内容”而不是“就是HTML的内容”?因为我们在开发中,在<template></template>标签中除了写一些原生HTML的标签,我们还会写一些变量插值,如,或者写一些Vue指令,如v-onv-if等。而这些东西都是在原生HTML语法中不存在的,不被接受的。但是事实上我们确实这么写了,也被正确识别了,页面也正常显示了,这又是为什么呢?

这就归功于Vue的模板编译了,Vue会把用户在<template></template>标签中写的类似于原生HTML的内容进行编译,把原生HTML的内容找出来,再把非原生HTML找出来,经过一系列的逻辑处理生成渲染函数,也就是render函数,而render函数会将模板内容生成对应的VNode,而VNode再经过前几篇文章介绍的patch过程从而得到将要渲染的视图中的VNode,最后根据VNode创建真实的DOM节点并插入到视图中, 最终完成视图的渲染更新。

而把用户在<template></template>标签中写的类似于原生HTML的内容进行编译,把原生HTML的内容找出来,再把非原生HTML找出来,经过一系列的逻辑处理生成渲染函数,也就是render函数的这一段过程称之为模板编译过程。

3. 整体渲染流程

所谓渲染流程,就是把用户写的类似于原生HTML的模板经过一系列处理最终反应到视图中称之为整个渲染流程。这个流程在上文中其实已经说到了,下面我们以流程图的形式宏观的了解一下,流程图如下: 

从图中我们也可以看到,模板编译过程就是把用户写的模板经过一系列处理最终生成render函数的过程。

4. 模板编译内部流程

那么模板编译内部是怎么把用户写的模板经过处理最终生成render函数的呢?这内部的过程是怎样的呢?

4.1 抽象语法树AST

我们知道,用户在<template></template>标签中写的模板对Vue来说就是一堆字符串,那么如何解析这一堆字符串并且从中提取出元素的标签、属性、变量插值等有效信息呢?这就需要借助一个叫做抽象语法树的东西。

所谓抽象语法树,在计算机科学中,抽象语法树AbstractSyntaxTree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。——来自百度百科

我就知道,这段话贴出来也是白贴,因为看了也看不懂,哈哈。那么我们就以最直观的例子来理解什么是抽象语法树。请看下图: 

从图中我们可以看到,一个简单的HTML标签的代码被转换成了一个JS对象,而这个对象中的属性代表了这个标签中一些关键有效信息。如图中标识。 有兴趣的同学可以在这个网站在线转换试试:https://astexplorer.net/

4.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; 其对应的源码如下:
// 源码位置: /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}
})

可以看到 baseCompile 的代码非常的简短主要核心代码。

  • 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 的返回值

{ast: ast,render: code.render,staticRenderFns: code.staticRenderFns}

最终返回了抽象语法树( ast ),渲染函数( render ),静态渲染函数( staticRenderFns ),且render 的值为code.renderstaticRenderFns 的值为code.staticRenderFns,也就是说通过 generate处理 ast之后得到的返回值 code 是一个对象。

下面再给出模板编译内部具体流程图,便于理解。流程图如下: 

5. 总结

本篇文章首先引出了为什么会有模板编译,因为有了模板编译,才有了虚拟DOM,才有了后续的视图更新。接着介绍了什么是模板编译,以及介绍了把用户所写的模板经过层层处理直到最终渲染的视图中这个整体的渲染流程;最后介绍了模板编译过程中所需要使用的抽象语法树的概念以及分析了模板编译的具体实施流程,其流程大致分为三个阶段,分别是模板解析阶段、优化阶段和代码生成阶段。那么接下来的几篇文章将会把这三个阶段逐一进行分析介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/255686.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 CKS 题库 | 4、RBAC - RoleBinding

CKS 题库 4、RBAC - RoleBinding Context 绑定到 Pod 的 ServiceAccount 的 Role 授予过度宽松的权限。完成以下项目以减少权限集。 Task 一个名为 web-pod 的现有 Pod 已在 namespace db 中运行。 编辑绑定到 Pod 的 ServiceAccount service-account-web 的现有 Role&#…

ChatGPT高效提问—prompt常见用法(续篇四)

ChatGPT高效提问—prompt常见用法&#xff08;续篇四&#xff09; 1.1 知识生成 ​ 知识生成是指使用自然语言处理技术&#xff0c;通过ChatGPT等AI模型生成与特定主题相关的知识、文本或回答。在知识生成过程中&#xff0c;模型接收prompt输入的问题、指令或上下文信息&…

HTTP 超文本传送协议

1 超文本传送协议 HTTP HTTP 是面向事务的 (transaction-oriented) 应用层协议。 使用 TCP 连接进行可靠的传送。 定义了浏览器与万维网服务器通信的格式和规则。 是万维网上能够可靠地交换文件&#xff08;包括文本、声音、图像等各种多媒体文件&#xff09;的重要基础。 H…

24个已知403绕过方法的利用脚本

介绍 一个简单的脚本&#xff0c;仅供自用&#xff0c;用于绕过 403 在curl的帮助下使用24个已知的403绕过方法 它还可用于比较各种条件下的响应&#xff0c;如下图所示 用法 ./bypass-403.sh https://example.com admin ./bypass-403.sh website-here path-here 安装 git …

新春快乐(烟花、春联)【附源码】

新春快乐 一&#xff1a; C语言 -- 烟花二&#xff1a;Python -- 春联三&#xff1a;Python -- 烟花四&#xff1a;HTML -- 烟花 一&#xff1a; C语言 – 烟花 运行效果&#xff1a; #include <graphics.h> #include <math.h> #include <time.h> #include…

深入学习《大学计算机》系列之第1章 1.7节——图灵机的一个例子

一.欢迎来到我的酒馆 第1章 1.7节&#xff0c;图灵机的一个例子。 目录 一.欢迎来到我的酒馆二.图灵机2.1 艾伦-图灵简介2.2 图灵机简介 三.图灵机工作原理3.1 使用图灵机打印二进制数3.2 图灵机工作原理总结 四.总结 二.图灵机 本节内容主要介绍计算机科学之父——艾伦-图灵、…

云卷云舒:论超级数据库、算网数据库、智算数据库

笔者大胆提出一种“超级数据库”的概念设想。 一、超级能力 就像当初提出“超级计算机”一样&#xff0c;我们是否同样可以提出“超级数据库”的概念呢&#xff1f;当然不是不可以。 二、超级计算机 我们回忆一下“超级计算机”的发展之路&#xff0c;大致经过了如下几个环…

详细分析Redis中数值乱码的根本原因以及解决方式

目录 前言1. 问题所示2. 原理分析3. 拓展 前言 对于这方面的相关知识推荐阅读&#xff1a; Redis框架从入门到学精&#xff08;全&#xff09;Java关于RedisTemplate的使用分析 附代码java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; …

单片机学习笔记---蜂鸣器播放提示音音乐(天空之城)

目录 蜂鸣器播放提示音 蜂鸣器播放音乐&#xff08;天空之城&#xff09; 准备工作 主程序 中断函数 上一节讲了蜂鸣器驱动原理和乐理基础知识&#xff0c;这一节开始代码演示&#xff01; 蜂鸣器播放提示音 先创建工程&#xff1a;蜂鸣器播放提示音 把我们之前模块化的…

Python 错误及其解决方法

Python 是一种易于学习的编程语言&#xff0c;但初学者在学习和使用 Python 的过程中难免会遇到一些错误。以下是一些常见的 Python 错误及其解决方法&#xff1a; 1. 语法错误&#xff08;SyntaxError&#xff09;&#xff1a; python # 错误示例 print("Hello, World!…

【计算机网络】【练习题及解答】【新加坡南洋理工大学】【Computer Control Network】【Exercise Solution】

说明&#xff1a; 个人资料&#xff0c;仅供学习使用&#xff0c;版权归校方所有。 一、题目描述 该问题接上期博文【练习题及解答】&#xff0c;描述网络通信中的链路效率&#xff08;Link Efficiency&#xff09;&#xff0c;即Link Utilization的计算。&#xff08;此处认…

第二届 N1CTF Junior WEB方向 部分题解WP

zako 题目描述&#xff1a;很简单的rce哦 启动环境&#xff0c;源码直接给了。 execute.sh #!/bin/bashreject(){echo ${1}exit 1 }XXXCMD$1awk -v str"${XXXCMD}" \ BEGIN{deny";&$(){}[]!#$%^&*-";for(i 1; i < length(str); i){char su…

Qt Windows和Android使用MuPDF预览PDF文件

文章目录 1. Windows MuPDF编译2. Android MuPDF编译3. 引用 MuPDF 库4. 解析本地PDF文件 1. Windows MuPDF编译 使用如下命令将MuPDF的源码克隆到本地 git clone --recursive git://git.ghostscript.com/mupdf.git直接用VS&#xff0c;打开 mupdf/platform/win32/mupdf.sln …

《CSS 简易速速上手小册》第10章:未来的 CSS(2024 最新版)

文章目录 10.1 CSS 的新特性和趋势10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 CSS Grid 创建响应式图库10.1.3 拓展案例 1&#xff1a;利用 CSS 变量实现主题切换10.1.4 拓展案例 2&#xff1a;使用 lab() 颜色和 layer 规则优化样式 10.2 CSS Houdini&#xff1a;魔法般…

【JMX】JAVA监控的基石

目录 1.概述 2.MBean 2.1.Standard MBean 2.2.Dynamic MBean 2.3.Model Bean 2.4.Dynamic MBean和Model Bean的区别 2.5.MXBean 2.6.Open Bean 3.控制台 1.概述 什么是JMX&#xff0c;首先来看一段对话&#xff1a; Java Management Extensions&#xff08;JMX&#…

四.Linux实用操作 12-14.环境变量文件的上传和下载压缩和解压

目录 四.Linux实用操作 12.环境变量 环境变量 环境变量--PATH $ 符号 自行设置环境变量 自定义环境变量PATH 总结 四.Linux实用操作 13.文件的上传和下载 上传&#xff0c;下载 rz&#xff0c;sz命令 四.Linux实用操作 14.压缩和解压 压缩格式 tar命令 tar命令压缩…

Java核心设计模式:代理设计模式

一、生活中常见的代理案例 房地产中介&#xff1a;客户手里没有房源信息&#xff0c;找一个中介帮忙商品代购&#xff1a;代理者一般有好的资源渠道&#xff0c;降低购物成本&#xff08;如海外代购&#xff0c;自己不用为了买东西出国&#xff09; 二、为什么要使用代理 对…

2024最新版Sublime Text 4安装使用指南

2024最新版Sublime Text 4安装使用指南 Installation and Usage Guide to the Latest Sublime Text 4 in 2024 By JacksonML 0. Sublime Text是什么&#xff1f; Sublime Text 由自定义组件构建&#xff0c;支持Python, Java, C/C等多种编程语言&#xff0c;并为用户提供无与…

第74讲Breadcrumb 面包屑实现

Breadcrumb 面包屑实现 为了实现二级路由&#xff0c;我们搞成搞个子路由&#xff0c;对于二级菜单 const routes [{path: /,name: 首页,component: () > import(../views/layout),redirect:/home,children:[{path: /home,name: 首页,component: () > import(../views…

Redis篇之过期淘汰策略

一、数据的过期策略 1.什么是过期策略 Redis对数据设置数据的有效时间&#xff0c;数据过期以后&#xff0c;就需要将数据从内存中删除掉。可以按照不同的规则进行删除&#xff0c;这种删除规则就被称之为数据的删除策略&#xff08;数据过期策略&#xff09;。 2.过期策略-惰…