coverPiccoverPic

模板编译的静态提升(v2)

前言

我们都知道…:

graph LR
O[baseCompile] -->|"①"| B[parse\n生成抽象语法树]
A[template 模板]-->|args|B-->|return|C[ast]
O-->|"②"|D[optimize\n标记静态节点]
C-->|args|D
C-->|args|E
O-->|"③"|E["generate\n生成 render 函数"]-->|return|F[render]

静态提升涉及的主要是optimize标记静态根节点,和generate生成代码。静态根节点的意思是它的子节点都是静态的,而且它的亲节点不是静态的(optimize标记静态根节点时,如果一个节点及其子节点都是静态的,就会跳出,也就是说,不会遍历到静态根节点的静态的子节点上面)。下面来看generate的逻辑:

generate

generate涉及到静态节点的逻辑很简单:

graph LR
C[generate]
C-->|"el.staticRoot && !el.staticProcessed"|D[genStatic]-->|递归返回|C

看看源码:

ts
  1. function genStatic(el: ASTElement, state: CodegenState): string {
  2. el.staticProcessed = true
  3. // 标记上下文是不是在 v-pre 的节点中,这个 state.pre 是用来让 template 标签保留源码的
  4. const originalPreState = state.pre
  5. if (el.pre) {
  6. state.pre = el.pre
  7. }
  8. state.staticRenderFns.push(`with(this){return ${genElement(el, state)}}`)
  9. state.pre = originalPreState
  10. return `_m(${state.staticRenderFns.length - 1}${
  11. // 标记在 v-for 循环里面
  12. el.staticInFor ? ',true' : ''
  13. })`
  14. }

state.staticRenderFns记录了所有静态提升的代码块,_m用于渲染state.staticRenderFns的节点,具体怎么做,后面再说。

0 条评论未登录用户
Ctrl or + Enter 评论
© 2023-2025 LittleRangiferTarandus, All rights reserved.
🌸 Run