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

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

模版编译

联系前文,讲了虚拟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;

对应源码如下:

// 源码位置: /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的返回值:

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

code是一个对象


http://www.mrgr.cn/news/45598.html

相关文章:

  • 【代码随想录Day37】动态规划Part06
  • 电影《749局》路演 苗苗演绎超能力少女分享幕后故事
  • JavaScript的内置对象有哪些?
  • Java基础(上)
  • 【牛客刷题实战】BC119 最高分与最低分之差
  • 开通商家转账到零钱技巧
  • 支持向量机SVM
  • cuda内存种类
  • Ubuntu2404配置本地离线源
  • 流浪地球行星发动机
  • HTB:Tactics[WriteUP]
  • C++——STL简介
  • 文件内容提取:Apache Tika 2.9.2
  • 有哪些工具可以辅助特定方法来提升DFT ATPG的coverage?
  • 26.删除有序数组中的重复项
  • vue3 对 vue2 有什么优势
  • 计组体系软考题2-计算机组成原理与计算机体系结构概论
  • Spring JDBC - Spring JDBC模版使用
  • 【C语言】指针和数组的内存使用详解
  • 【漏洞复现】飞企互联 FE企业运营管理平台 treeXml.jsp SQL注入漏洞