“This is the 25th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

Optimize and generate functions

How do we convert optimized AST objects into JS code in Vue

Optimize function

  • Optimize the abstract syntax tree to detect whether the child nodes are pure static nodes

  • Once a purely static node is detected, for example:

    <div>Hello </div>
    Copy the code

    Nodes that never change

    • Upgrade to constant. Nodes are not recreated during re-rendering
    • The static subtree is directly skipped during patch

generateFunction – parameter

Generate function: takes two arguments:

  • ast: optimizedastObject,
  • options: Option object

The code returned is the JS code

 // Generate the abstract syntax tree as a string of JS code
 const code = generate(ast, options)
Copy the code

The generate parsing

This function is very simple in terms of the number of lines, just three sentences

export function generate (
  ast: ASTElement | void,
  options: CompilerOptions
) :CodegenResult {
  const state = new CodegenState(options)
  const code = ast ? genElement(ast, state) : '_c("div")'
  return {
    render: `with(this){return ${code}} `.staticRenderFns: state.staticRenderFns
  }
}
Copy the code
  1. createCodegenStateObject is the state object used during code generation
  2. judgeastIf there is a
    • Presence: callgenElementStart generating code
    • There is no:_c("div")String code
  3. The return value

Let’s focus on the generation of the static root node: staticRenderFns

CodegenState class

The CodegenState class we need to focus on is staticRenderFns, Pre

  • staticRenderFns: is used to store code generated by static root nodes, as there may be multiple static root nodes in a template
  • pre: Records whether the node being processed is in usev-preOf the tag

When we have created the corresponding class, we will call genElement to add data to state.Staticrenderfns

GenElement method

export function genElement (el: ASTElement, state: CodegenState) :string {
  if (el.parent) {
    el.pre = el.pre || el.parent.pre
  }

  if(el.staticRoot && ! el.staticProcessed) {return genStatic(el, state)
  } 
  ...
}
Copy the code

In genStatic we add the corresponding data to the static node

function genStatic (el: ASTElement, state: CodegenState) :string {... state.staticRenderFns.push(`with(this){return ${genElement(el, state)}} `)... }Copy the code

StaticRenderFns is an array because you can have multiple static child nodes in a template, and then you need to call the _m method in SRC \ Core \instance\render-helpers\index.js