一、目的
模版编译的目的就是将模版template转换成渲染函数render
AST: 对象形式描述的树形代码结构
- 模板编译是将字符串模板转换成AST对象
- 优化AST对象,过程是标记静态根节点
- 优化好的AST转换成字符串形式代码,之后通过newFunction转换成方法
- 这方法就是最终的render函数
一、入口函数compileToFunctions(template, ...)
- 位置
src/platforms/web/entry-runtime-with-compiler.js
/**
* 把模版编译成render函数
* @param {*}
* @return {*}
*/
Vue.prototype.$mount = function (
...
// 把 template 转换成 render 函数
const { render, staticRenderFns } = compileToFunctions(template, {
...
}, this)
...
// 调用 mount 方法,渲染 DOM
return mount.call(this, el, hydrating)
}
- 调用
createCompiler(baseOptions)
- 调用
createCompilerCreator
// `createCompilerCreator` allows creating compilers that use alternative
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
// Here we just export a default compiler using the default parts.
export const createCompiler = createCompilerCreator(function baseCompile (
template: string,
options: CompilerOptions
): CompiledResult {
// 把模板转换成 ast 抽象语法树
// 抽象语法树,用来以树形的方式描述代码结构
const ast = parse(template.trim(), options)
if (options.optimize !== false) {
// 优化抽象语法树
optimize(ast, options)
}
// 把抽象语法树生成字符串形式的 js 代码
const code = generate(ast, options)
return {
ast,
// 渲染函数
render: code.render,
// 静态渲染函数,生成静态 VNode 树
staticRenderFns: code.staticRenderFns
}
})
三、compile(template, options)
- 合并options
- baseCompile(template.trim(),finalOptions)
三、baseCompile(template.trim(),finalOptions)
parse(template.trim(), options)
把模板转换成 ast 抽象语法树optimize(ast, options)
-
- 标记AST tree树种的静态节点
-
- 检测到静态节点、设置为静态、不需要在每次重新渲染时重新生成节点
-
- patch静态跳过静态节点
generate(ast, options)
把抽象语法树生成字符串形式的 js 代码
四、compileToFunctions(template, ...)
- 继续把上一步生成的JS代码转换成函数
- createFunction
- render和 staticRenderFns初始化完毕, 挂载到vue实例的options对应的属性中