Skip to content

重学vue-01模板语法 中,我们知道了Vue对外的版本分为完整版和runtime版,完整版比runtime版多了模板编译器

用打包工具时,最终打好的包里实际上是不需要编译器的,所以只用运行时版本即可.

因为运行时版本相比完整版体积要小大约 30%,所以应该尽可能使用这个版本,打包工具引入的资源默认是运行时版本的

这大出来30%的编译器,能让我们写template字符串,在浏览器运行时解析成 render函数 再执行生成 VNode,渲染生成 真实DOM

我们尝试实现这部分的编译器(template字符串 -> render函数体) 分析阶段

  • 解析器
  • 优化器
  • 代码生成器

解析器

把模板字符串解析层AST对象

js
class compiler {
  constructor(template) {
    this.init(template)
  }
  parseHTML(template,hookObj) {
    console.log(template)
  }
  init(template) {
    this.parseHTML(template,{
      startHook() { console.log('startHook') }, // 标签开始时触发钩子
      endHook() {}, // 标签结束时触发钩子
      stringHook() {}, // 字符串时触发钩子
      commentHook() {}, // 注释时触发钩子
    })
  }
}
new compiler('<div>1</div>')

解析器的内部原理是一小段一小段地截取模板字符串,每截取一小段字符串,就会根据截取出来的字符串类型触发不同的钩子函数,直到模板字符串截空停止运行

优化器

遍历AST标记静态节点

js
optimize (AST) {
  if (!AST) return
  // 第一步:标记所有静态节点
  markStatic(AST)
  // 第二步:标记所有静态根节点
  markStaticRoots(AST)
}

代码生成器

遍历AST 生成并拼接字符串,new Function创建出render函数

打包工具的编译

除了👆完整版vue里有模版语法的编译器,依靠打包工具来编译的模板语法的编译器,我们也来看看

同样的vue-loader,解析出.vue文件中的template部分出来后,会进行转译成AST,打标记,生成render字符串等步骤

思考🤔: template配置的那种写法也是vue-loader做的编译吗