行文介绍
本文主要介绍vue中template compile的主体思路和源码流程。
适合想要梳理模板编译对应的源码函数调用流程的童鞋。为大家滤清思路。
具体的分析请查看文末参考链接。
主体思路
三步走:
- 将模板解析为AST。
parse
。parse使用正则等方式解析template模板中的指令,class,style等数据,形成AST - 优化AST。
optimize
。主要作用是标记static静态节点,后面当update更新界面时,会有diff的过程,会直接跳过静态节点,从而减少比较过程,优化patch性能。 - 将AST转换为
render
函数。generate。将AST转换为render function字符串,得到结果是render字符串以及staticRenderFns字符串。
源码函数调用流程
整个源码非常贴近函数式编程,但是也导致阅读理解的成本很高,基本都是高阶函数,函数被传入传出的,很容易被绕晕。
但是抓住核心就行,createCompiler
函数。
核心函数
createCompiler
简要流程
compileToFunctions
<==
createCompiler
<==
createCompilerCreator
<==
createCompileToFunctionFn
<==
createFunction
详细流程
// src/platforms/web/entry-runtime-with-compiler.js
const { render, staticRenderFns } = compileToFunctions(template, {
outputSourceRange: process.env.NODE_ENV !== 'production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
// src/platforms/web/compiler/index.js
const { compile, compileToFunctions } = createCompiler(baseOptions)
// src/compiler/index.js
export const createCompiler = createCompilerCreator(function baseCompile (
template: string,
options: CompilerOptions
): CompiledResult {
// 三步走 parse optimize generate
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
}
})
// src/compiler/create-compiler.js
export function createCompilerCreator (baseCompile: Function): Function {
return function createCompiler (baseOptions: CompilerOptions) {
function compile (
template: string,
options?: CompilerOptions
): CompiledResult {
const compiled = baseCompile(template.trim(), finalOptions)
...
return compiled
}
return {
compile,
// 真实使用的是这个函数compileToFunctions
compileToFunctions: createCompileToFunctionFn(compile)
}
}
}
// src/compiler/to-function.js
export function createCompileToFunctionFn (compile: Function): Function {
return function compileToFunctions (
template: string,
options?: CompilerOptions,
vm?: Component
): CompiledFunctionResult {
// compile
const compiled = compile(template, options)
res.render = createFunction(compiled.render, fnGenErrors)
return (cache[key] = res)
}
}
// src/compiler/to-function.js
function createFunction (code, errors) {
try {
return new Function(code)
} catch (err) {
errors.push({ err, code })
return noop
}
}
参考链接
https://github.com/answershut... 【这篇文章不错,推荐阅读】
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。