Home > Web Front-end > Vue.js > Vue learning talks about template compilation principles

Vue learning talks about template compilation principles

青灯夜游
Release: 2023-03-07 19:01:00
forward
1532 people have browsed it

What is template compilation? The following article will talk about template compilation in Vue and discuss the principles of template compilation. I hope it will be helpful to you!

Vue learning talks about template compilation principles

vue provides template syntax that allows us to declaratively describe the binding relationship between state and DOM, such as <p>{{name}} </p> <p></p>.

Template compilation refers to the process in which the template is compiled into a render function. The function of the render function is to generate a new vnode based on the latest status each time it is executed.

The compilation process is: Template as input-> Template compilation stage->Generate rendering function

##Interview questions

    vue template compilation?
  • Explanation of render in template compilation Compiler?
  • vue template compilation process, explain in detail what is done in each process
  • Template compilation, who will parse the AST tree [Related recommendations:
  • vuejs video tutorial, Web front-end development

#Compile the template into a rendering function

Vue learning talks about template compilation principles

  • Parser: Parse the template into AST (Abstract Syntax Tree)
  • Optimizer: Traverse AST to mark static nodes, because static Nodes are immutable. There is no need to create new virtual nodes for labeled static nodes. You can directly clone existing virtual nodes.
  • Code Generator: Use AST to generate rendering functions. Convert AST into code string. Put the code string into the rendering function and export it for use by the outside world.

Case

Vue learning talks about template compilation principles

1. Template confirmation

Assume that the following code has

el, template, render, $mount

//复杂案例
let vue = new Vue({
    el: &#39;#app&#39;,
    data() {
        return {
            a: 1,
            b: [1]
        }
    },
    render(h) {
        return h(&#39;div&#39;, { id: &#39;hhh&#39; }, &#39;hello&#39;)
    },
    template: `<div id=&#39;hhh&#39; style="aa:1;bb:2"><a>{{xxx}}{{ccc}}</a></div>`
}).$mount(&#39;#app&#39;)

console.log(vue)

//脚手架创建的案例
let vue = new Vue({
  render: h => h(App)
}).$mount(&#39;#app&#39;)
Copy after login

Vue learning talks about template compilation principles

#1) Which root node to render to : Determine whether there is an el attribute. If there is, get the el root node directly. If not, get it when calling $mount. Root node

2) Which template to render to the root node: Whether to call the render function to pass in the templaterender: h => h(App ) ->

    With render: At this time, the render function is executed first,
  • render priority> template
  • No render:
    • With template: template is parsed into the required format of the render function - a code string, and rendered using the render function call
    • Without template: outerHTML parsing of the el root node into the format required by the render function - a code string, and use the render function to render
    • 3. Rendering method: No matter what the situation, the final step is to
      use the render function to render

2. Parser-parse the template into AST

Parser-parse the template into AST

<div>
  <p>{{name}}</p>
</div>
Copy after login

After parsing the above template into AST, the AST abstract syntax tree uses objects in JS to describe a node, and one object represents a node.

{
  tag: "div"
  type: 1, //节点类型
  staticRoot: false,
  static: false,
  plain: true,
  parent: undefined, //存放父节点
  attrsList: [],
  attrsMap: {},
  children: [ //存放孩子节点
      {
      tag: "p"
      type: 1,
      staticRoot: false,
      static: false,
      plain: true,
      parent: {tag: "div", ...},
      attrsList: [],
      attrsMap: {},
      children: [{
          type: 2,
          text: "{{name}}",
          static: false,
          expression: "_s(name)"
      }]
    }
  ]
}
Copy after login

The working principle of the parser

The principle of the parser is to intercept the template string in small sections, each time Intercepting a small string will trigger different hook functions according to the type of the intercepted string until the template string is intercepted. Then use the stack to determine the hierarchical relationship

The internal part of the parser is also divided into several sub-parsers, such as HTML parser, text parser, etc.

The role of the HTML parser is to parse HTML. In the process of parsing HTML, various hook functions are continuously triggered.

    The hook function of the start tag can Constructing nodes of element type
  • Text type nodes can be constructed in the text hook function
  • Comment type nodes can be constructed in the comment hook function
  • End tag hook function
The text parser performs secondary processing on the text parsed from HTML, such as interpolation syntax

{{}}

How to determine the level between DOM relation? Using the stack When triggering the hook function of the start tag, if the current tag is not a self-closing tag,
pushentersstack. When the hook function of the end tag is triggered,
pop comes out from the stack

3. Optimizer-mark static nodes in AST

Benefits of marking static subtrees

  • 每次重新渲染时,不需要为静态子树创建新虚拟子树,克隆已存在的静态子树
  • 在虚拟DOM中打补丁(patching)的过程可以跳过 ,静态子树是不可变的

优化器的内部实现主要分两步用递归的方式将所有节点添加 static 属性,true表示是静态的,false表示不是静态的。

  • 在AST中找出所有静态节点并打上标记
    静态节点:DOM不会发生变化的节点
    通过递归的方式从上向下标记静态节点,如果一个节点被标记为静态节点,但它的子节点却被标记为动态节点,就说明该节点不是静态节点,可以将它改为动态节点。静态节点的特征是它的子节点也必须是静态的。

静态根节点也是静态节点

  • **在AST中找出所有静态根节点并打上标记 **
    静态根节点:子节点全是静态节点的节点
    使用递归从上向下寻找,在寻找的过程中遇见的第一个静态节点就为静态根节点,同时不继续往下找。

如果一个静态根节点的子节点只有一个文本节点或没有子节点,那么不会标记成静态根节点,即使他们是,因为优化成本大于收益

怎么判断是否静态节点?
在将模板字符串解析成AST的时候,会根据不同的文本类型设置一个 type

type说明是否时静态节点
1元素节点进行一些排除
2带遍历的动态文本节点不是
3不带遍历的纯文本节点

4.代码生成器-将AST转化成渲染函数中的代码字符串

代码生成器的作用:将AST转化成渲染函数中的代码字符串

<div>
  <p>{{name}}</p>
</div>
//生成的render渲染函数
{
  render: `with(this){return _c('div',[_c('p',[_v(_s(name))])])}`
}
//格式化后
with(this){
  return _c(
    'div',
    [
      _c(
        'p',
        [
          _v(_s(name))
        ]
      )
    ]
  )
}
Copy after login

生成代码字符串是一个递归的过程,从顶向下依次处理每一个AST节点。
节点有三种类型,分别对应三种不同的创建方法与别名。

类型 创建方法 别名
元素节点 createElement _c
文本节点 createTextVNode _v
注释节点 createEmptyVNode _e

渲染函数可以生成VNode的原因:渲染函数其实是执行了createElement,而createElement可以创建VNode。

代码字符串的拼接过程

递归AST来生成字符串,最先生成根节点,然后在子节点字符串生成后,将其拼接在根节点的参数中,子节点的子节点拼接在子节点的参数中,一层层拼接。

(学习视频分享:vuejs入门教程编程基础视频

The above is the detailed content of Vue learning talks about template compilation principles. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template