最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue源码之compile之generate

    正文概述 掘金(派大星的黑板报)   2021-02-25   714

    generate

    Vue源码之compile之generate
    Vue源码之compile之generate

    generate 函数⾸先实例化CodegenState然后通过 genElement(ast, state) ⽣成 code ,再把 code ⽤ with(this){return ${code}}} 包裹起来放到render中。

    CodegenState

    Vue源码之compile之generate

    options 是传入的一些判断函数或者指令函数,CodegenState初始化实例的编译状态,因为这个函数是给实例初始化一些属性的,看到很明显就是给实例添加上了很多属性,this.xxxx 什么的。

    • dataGenFns
    Vue源码之compile之generate
    • directives

    这也是个数组,存放的是 Vue 自有指令的独属处理函数,包括以下几个指令的处理函数
    v-on:绑定事件
    v-bind:绑定属性
    v-cloak:编译前隐藏DOM
    v-model:双向绑定
    v-text:插入文本
    v-html:插入html
    当你在模板中使用到以上的指令的时候,Vue 会调用相应的函数先进行处理

    • staticRenderFns

    一个数组,用来存放静态根节点的render 函数,每个实例都独有这个属性,如果没有静态根节点就为空。

    genElement

    Vue源码之compile之generate

    可以看到基本就是递归判断当前 AST 元素节点的属性执⾏不同的代码⽣成函数。不要尝试去一下子看完全部,应该根据场景对应去阅读才是正解。

    genStatic 对于静态节点的处理

    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate

    1.首先genElement判断el节点是否存在staticRoot标识,并且一开始staticProcessed为false,如果满足这两个条件就调用genStatic函数。

    2.genStatic首先把staticProcessed设为true,其次往staticRenderFns丢入genElement返回结果,最后render中code的返回值为_m(staticRenderFns.length - 1)。

    3.再次genElement时staticProcessed为true就往下执行,执行genData中的属性的解析,然后进行genChildren,遍历children执行genNode,如果子节点类型为1说明是元素节点继续执行genElement,如果不是元素节点也不是注释节点那么就调用genText,判断是否为表达式返回对应的编码。

    4.最终遍历结束后就得到了最终的编码,对于静态节点这段编码存放在staticRenderFns中。

    genOnce 对v-once的处理

    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate

    1.首先执行genElement外层标签不存在标识直接执行到genData然后执行genChildren,然后执行genCode,因为为元素节点所以继续执行genElement。

    2.这时el存在once 标识,并且一开始onceProcessed为false,调用genOnce函数。

    3.genOnce首先把onceProcessed 设为true,如果没有el.if && !el.ifProcessed和el.staticInFor条件不满足执行genStatic(el, state)。

    4.genStatic首先把staticProcessed设为true,其次往staticRenderFns丢入genElement返回结果,最后render中children的返回值为_m(staticRenderFns.length - 1)。

    5.再次genElement时staticProcessed为true就往下执行,执行genData解析,然后进行genChildren,遍历children执行genNode,如果子节点类型为1说明是元素节点继续执行genElement,如果不是元素节点也不是注释节点那么就调用genText,判断是否为表达式返回对应的编码。

    6.最终遍历结束后就得到了最终的编码,对于静态节点这段编码存放在staticRenderFns中。

    genFor

    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate

    1.首先执行genElement外层标签不存在标识直接执行到genData然后执行genChildren,因为存在el.for,所以执行genElement。

    2.这时el存在for标识,并且一开始forProcessed为false,调用genFor函数。

    3.genFor首先获取到el.for,el.alias和el.iterator1,然后执行一些报错其中有没写Key的报错,把forProcessed设为true,然后返回了for的编码_l…然后执行genElement。

    5.再次genElement时staticProcessed为true就往下执行,存在el.key执行genData对key的解析,然后进行genChildren,遍历children执行genNode,如果子节点类型为1说明是元素节点继续执行genElement,如果不是元素节点也不是注释节点那么就调用genText,判断是否为表达式返回对应的编码。

    6.最终遍历结束后就得到了最终的编码。

    genIf

    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate

    1.首先执行genElement外层标签不存在标识直接执行到genData然后执行genChildren,因为存在el.for,所以执行genElement。

    2.这时el存在if标识,并且一开始ifProcessed为false,调用genIf函数。

    3.genIf首先把ifProcessed设为true,然后执行genIfConditions函数传入el.ifConditions.slice()。

    4.如果没有condition直接返回'_e()',否则从conditions.shift()推出一位,如果condition存在表达式,返回三元表达式,条件?genTernaryExp -> 也就是genElement解析节点 : genIfConditions 再次执行genIfConditions
    如果不存在表达式直接调用genTernaryExp去解析节点。

    5.最终遍历结束后就得到了最终的编码。

    class和style

    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate
    Vue源码之compile之generate

    1.首先执行genElement外层标签不存在标识直接执行到genData然后执行genChildren,因为也不存在标识直接执行到genData。

    2.此时genData对el做dataGenFns处理,dataGenFns是平台用来处理class和style的,最终返回对象。

    3.处理完data后执行genChildren,遍历children执行genNode,如果子节点类型为1说明是元素节点继续执行genElement,如果不是元素节点也不是注释节点那么就调用genText,判断是否为表达式返回对应的编码。

    总结

    通过对一些指令的解析,我们对从 ast -> code 这⼀步有了⼀些了解,编译后⽣成的代码就是在render时执⾏的代码。由于 genCode 的内容有很多,大概思路都是差不多,无非就是根据不同的节点属性去走不同的流程生成不同的结果,最后拼接起来的一个字符串。至于slot和事件我们后面再单独说,又是烧脑的一天。加油打工人。


    起源地下载网 » Vue源码之compile之generate

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元