我们打开“src/compiler/to-function.js”文件,代码如下:
export function createCompileToFunctionFn (compile: Function): Function { const cache = Object.create(null) return function compileToFunctions ( template: string, options?: CompilerOptions, vm?: Component ): CompiledFunctionResult { options = extend({}, options) const warn = options.warn || baseWarn delete options.warn // ...省略部分代码 // check cache const key = options.delimiters ? String(options.delimiters) + template : template if (cache[key]) { return cache[key] } // compile const compiled = compile(template, options) // check compilation errors/tips if (process.env.NODE_ENV !== 'production') { if (compiled.errors && compiled.errors.length) { if (options.outputSourceRange) { compiled.errors.forEach(e => { warn( `Error compiling template:${e.msg}` +generateCodeFrame(template, e.start, e.end),vm) }) } else { warn(`Error compiling template:${template}` +compiled.errors.map(e => `- ${e}`).join('') + '',vm) } } if (compiled.tips && compiled.tips.length) { if (options.outputSourceRange) { compiled.tips.forEach(e => tip(e.msg, vm)) } else { compiled.tips.forEach(msg => tip(msg, vm)) } } } // turn code into functions const res = {} const fnGenErrors = [] res.render = createFunction(compiled.render, fnGenErrors) res.staticRenderFns = compiled.staticRenderFns.map(code => { return createFunction(code, fnGenErrors) }) if (process.env.NODE_ENV !== 'production') { if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) { warn(`Failed to generate render function:` +fnGenErrors.map(({ err, code }) => `${err.toString()} in${code}`).join(''),vm) } } return (cache[key] = res) }}
该函数其实主要是3个过程:
1、是否存在编译缓存
2、编译模板(compile)
3、返回编译结果,并缓存
接下来,我们一起拆分一下函数:
const key = options.delimiters ? String(options.delimiters) + template : template if (cache[key]) { return cache[key] }
定义 "key" 变量,如果存在自定义分隔符(delimiters)那就是 “delimiters” 和 “template”组合,否则就是 "template"。
然后就是判断是否有缓存,如果存在没救直接返回缓存。
// compileconst compiled = compile(template, options)
模板编译,核心的模板解析函数入口。
const res = {} const fnGenErrors = [] res.render = createFunction(compiled.render, fnGenErrors) res.staticRenderFns = compiled.staticRenderFns.map(code => { return createFunction(code, fnGenErrors) }) if (process.env.NODE_ENV !== 'production') { if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) { warn(`Failed to generate render function:` +fnGenErrors.map(({ err, code }) => `${err.toString()} in${code}`).join(''),vm) } } return (cache[key] = res)
将编译过后的 “render” 属性代码转换为函数,最后编译结果,并缓存。