【vue】vue模版编译的过程

一、什么是模版编译

在这里插入图片描述

二、整体渲染流程

所谓渲染流程,就是把用户写的类似于原生HTML的模板经过一系列处理最终反应到视图中称之为整个渲染流程。流程图如下:
在这里插入图片描述
从图中我们也可以看到,模板编译过程就是把用户写的模板经过一系列处理最终生成render函数的过程

三、模板编译内部流程

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

3.1抽象语法树AST

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

以最直观的例子来理解什么是抽象语法树。请看下图:
在这里插入图片描述
从图中我们可以看到,一个简单的HTML标签的代码被转换成了一个JS对象,而这个对象中的属性代表了这个标签中一些关键有效信息。

3.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.js

export const createCompiler = createCompilerCreator(function baseCompile (
  template: string,
  options: CompilerOptions
): CompiledResult {
    
    
  // 模板解析阶段:用正则等方式解析 template 模板中的指令、class、style等数据,形成AST
  const ast = parse(template.trim(), options)
  if (options.optimize !== false) {
    
    
    // 优化阶段:遍历AST,找出其中的静态节点,并打上标记;
    // 优化的目标:生成模板AST树,检测不需要进行DOM改变的静态子树。一旦检测到这些静态树,我们就能做以下这些事情:
    // 1.把它们变成常数,这样我们就再也不需要每次重新渲染时创建新的节点了
    // 2.在patch的过程中直接跳过
    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 是一个对象。

下面再给出模板编译内部具体流程图,便于理解。流程图如下:
在这里插入图片描述
vue官网描述

推荐阅读:Vue源码之:模板编译三大阶段

猜你喜欢

转载自blog.csdn.net/weixin_44761091/article/details/124198657