Template compilation
1. The concept
The main goal of template compilation is to convert a template to a render function.
2. Necessity of template compilation
Vue2.0 requires the use of VNode to describe views and various interactions. It is not feasible for developers to write render functions by hand, so developers need to write A Vue template that looks like HTML code and the compiler converts the template into a RENDER function that returns VNode.
3. Output after the template is compiled
In versions with a compiler, templates can be declared using template or EL
with(this) {return _c('div', {attrs: {"id":"demo"}},[_m(0),_v(""),(foo)? _c('p',[_v(_s(foo))]):_e(),_v(""),_c('comp', {on: {"myclick":onMyClick}})],1)}
Copy the code
_c is the createElement alias
There are two time points for template execution :(with or without compiler) 1) precompile before webpack runtime 2) directly introduce vue.js mode, then own compiler, el or template, compile in real time
4. The overall process of vue source template compilation
Template will be compileToFunctions when the $mount entry is mounted
Location: platform/web/entry – the runtime – with – compiler. Js
Function: If the template or EL option is specified, compilation is performed
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
) :Component {
const { render, staticRenderFns } = compileToFunctions(template, {
outputSourceRange: process.env.NODE_ENV ! = ='production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = render
options.staticRenderFns = staticRenderFns
}
Copy the code
2) Compilation process
Location: SRC/compiler/index. Js
export const createCompiler = createCompilerCreator(function baseCompile (template: string, options: CompilerOptions) :CompiledResult {
const ast = parse(template.trim(), options)
if(options.optimize ! = =false) {
optimize(ast, options)
}
const code = generate(ast, options)
return {
ast,
render: code.render,
staticRenderFns: code.staticRenderFns
}
})
Copy the code
3) Compile three stages
- Parse
The parser parses the template into an abstract syntax tree AST, and only after the template is parsed into an AST can it be used to optimize or prop up code strings
Location: the SRC/compiler/parser/index. Js
HTML parser, text parser, filter parser, and the most important HTML parser:
parseHTML(tempalte, {
start(tag, attrs, unary){}, // Start tag processing is encountered
end(){},// An end tag is encountered
chars(text){},// Text label processing is encountered
comment(text){}// A comment tag is encountered
})
Copy the code
Using the Chrome debugging tool, obtain the AST structure as follows:
-
Optimize
The optimizer’s job is to find and label static subtrees in the AST. Static subtrees are nodes that never change in the AST, such as plain text nodes.
Benefits of marking static subtrees:
- There is no need to create a new node for a static subtree each time you re-render
- When patch is created in the virtual DOM, static subtrees can be skipped
<! To create a nested relationship --><h1>Vue<span>Template compilation</span></h1> Copy the code
Location: SRC/compiler/optimizer. Js – optimize
- Generate
Convert the AST into the content of the rendering function, which is the code string.
Location: the SRC/compiler/codegen/index. Js
code = "_c('div',{attrs:{"id":"demo"}},[_m(0),_v(" "),(foo)? _c('p',[_v(_s(foo))]):_e(),_v(" "),_c('comp',{on:{"myclick":onMyClick}})],1)"
Copy the code