“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
generate
Function – parameter
Generate function: takes two arguments:
ast
: optimizedast
Object,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
- create
CodegenState
Object is the state object used during code generation - judge
ast
If there is a- Presence: call
genElement
Start generating code - There is no:
_c("div")
String code
- Presence: call
- 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 templatepre
: Records whether the node being processed is in usev-pre
Of 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