模板编译的主要目标是将模板(template)转换为渲染函数(render)
const app = new Vue()
打印出app.$options.render
image.png
<com foo="foo" :bar="foo"></comp>
image.png
多了以对象attrs传入,前面的foo是字符串,后面的是变量foo,由于传入的this是组件,所以相当于是this.foo,执行render函数就会触发this.foo的get,触发依赖收集
_c返回vnode,createElement
_v创建文本节点
_s格式化函数
其他helps (src/core/instance/render-helps/index.js installRenderHelpers)
image.png
整体流程
src/platforms/web/entry-runtime-with-compiler.js
compileToFunctions把template字符串转换为render函数
createCompilerCreator
parse(编译):将字符串模板便以为AST(抽象语法树),AST是js对象 类似vnode,为了做优化
里面是一堆正则,处理字符串模板,v-model,v-for,v-if.....
最后得出完整的AST数
src/compiler/parser/index.js
解析html
parseHTML()
start:创建AST实例 给AST挂载属性 指令 过滤器等
结构性执行处理v-for v-if once指令处理
v-if处理流程
processIf() 解析v-if指令得到表达式
把表达式赋值给AST的if属性
addIfCondition() 把ifConditions数组赋值给AST对象 里面有表达式和block
代码生成 src/compiler/codegen/index.js
genifConditions->genTernaryExp()生成三元表达式:genIfConditions()生成空对象
optimize(优化)静态化(没有变化就是静态化),有两个标记static、staticRoot标明是否静态化,一般单层标签不做静态化标记,里面再嵌套一层就会做静态化标记
src/compiler/optimize.js
optimize()
标记静态属性static
标记静态根节点staticRoot 真正跳过是这个
generate(生成)AST转化为代码字符串function,generate返回一个对象。里面有一个render和staticRenderFns
compileToFunctions->createFunction把render字符串变成render函数
PS:v-if v-for指令要经过编译过程 不能写在render函数里面 否则不能用
render函数里面可以写if语句 for语句










网友评论