c语言编程笔录

首页 >   > 笔记大全

笔记大全

vue学习之聊聊关于模板编译原理

更新时间:2023-12-06

1. 模板编译的作用

Vue.js采用了基于HTML模板的方式来定义用户界面,模板编译的作用就是将我们定义的模板转化为渲染函数,这个渲染函数可以被Vue实例所渲染。在Vue.js中,我们通常使用即带即编译的模板,在组件创建时,Vue.js会将模板字符串编译成渲染函数并缓存起来,以便后续的渲染操作可以直接使用缓存的渲染函数,而不需要重新编译模板。

// 创建组件时传入模板
Vue.component('my-component', {
  template: '
{{ message }}
', data: function () { return { message: 'hello Vue!' } } })

2. 模板编译的过程

模板编译的过程分为三个阶段:parse、optimize和生成render函数。在parse阶段,模板字符串会被解析成一棵抽象语法树(AST),在AST上可以进行优化操作,在optimize阶段就是对AST进行优化处理,优化后的AST会被用来生成render函数。最后是生成render函数阶段,将AST转化成JavaScript代码,生成render函数。

// 模板字符串
const templateStr = '
{{ message }}
' // 解析为AST const ast = parse(templateStr) // 优化AST const optimizedAst = optimize(ast) // 生成render函数 const code = generate(optimizedAst) // 将生成的render函数挂载到组件上 Vue.component('my-component', { render: code.render, staticRenderFns: code.staticRenderFns, data: function () { return { message: 'hello Vue!' } } })

3. 模板编译的优化

在optimize阶段,可以对AST进行优化处理,常用的优化方法有静态节点优化和静态属性提取。

静态节点优化指的是在AST中找出所有静态节点,将其打上标记,渲染时直接跳过这些节点的渲染,从而减少不必要的计算。

// AST
{
  type: 1,
  tag: 'div',
  attrsList: [],
  attrsMap: {},
  children: [
    {
      type: 2,
      text: 'hello Vue!',
      static: true // 标记为静态节点
    }
  ],
  static: false
}

// 优化后的AST
{
  type: 1,
  tag: 'div',
  attrsList: [],
  attrsMap: {},
  children: [
    {
      type: 2,
      text: 'hello Vue!',
      static: true
    }
  ],
  static: true // 标记整个节点为静态节点,渲染时跳过
}

静态属性提取指的是提取所有静态属性,将其存储下来,渲染时只需要用静态属性的值替换对应的属性即可,也可以减少不必要的计算。

// AST
{
  type: 1,
  tag: 'div',
  attrsList: [
    {
      name: 'class',
      value: 'header',
      dynamic: false,
      start: 5,
      end: 20
    }
  ],
  attrsMap: {
    class: 'header'
  },
  children: [
    {
      type: 2,
      text: 'hello Vue!'
    }
  ],
  static: false
}

// 优化后的AST
{
  type: 1,
  tag: 'div',
  attrsList: [
    {
      name: ':class',
      value: '_c("header")',
      dynamic: false,
      start: 5,
      end: 20
    }
  ],
  attrsMap: {
    ':class': '_c("header")'
  },
  staticClass: 'header', // 存储静态class的值
  classBinding: null,
  children: [
    {
      type: 2,
      text: 'hello Vue!'
    }
  ],
  static: false
}

4. 模板编译的调试

在Vue.js的开发模式中,模板编译过程可能会存在一些错误,可以通过开启编译调试模式来定位错误。开启调试模式后,会在生成的渲染函数中添加标记,以便能够快速定位编译错误的位置。

// 开启编译调试模式
Vue.config.debug = true
Vue.config.devtools = true

// 打开浏览器开发者工具,在console中输出生成的渲染函数
console.log(code.render.toString())

输出结果中标记为红色的代码为编译时出现错误的位置。