美文网首页
模板编译

模板编译

作者: key君 | 来源:发表于2019-10-14 20:22 被阅读0次
模板编译的主要目标是将模板(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语句

相关文章

网友评论

      本文标题:模板编译

      本文链接:https://www.haomeiwen.com/subject/nvbrmctx.html