当前位置:首页 > VUE

vue compile源码实现

2026-01-16 08:16:13VUE

Vue 的模板编译(compile)是将模板字符串转换为渲染函数的过程,涉及解析、优化和代码生成三个阶段。以下是其核心实现原理的分析:

解析阶段(Parse)

将模板字符串转换为抽象语法树(AST),主要通过正则表达式和字符串处理完成。

模板解析示例

<div id="app">{{ message }}</div>

会被解析为类似以下的 AST 结构:

{
  type: 1, // 元素节点
  tag: 'div',
  attrsList: [{ name: 'id', value: 'app' }],
  children: [{
    type: 2, // 文本节点
    expression: '_s(message)',
    text: '{{ message }}'
  }]
}

关键代码

// src/compiler/parser/index.js
export function parse(template, options) {
  const stack = []
  let root
  let currentParent
  parseHTML(template, {
    start(tag, attrs) {
      // 处理开始标签
      const element = createASTElement(tag, attrs)
      if (!root) root = element
      if (currentParent) currentParent.children.push(element)
      stack.push(element)
      currentParent = element
    },
    end() {
      // 处理结束标签
      stack.pop()
      currentParent = stack[stack.length - 1]
    },
    chars(text) {
      // 处理文本
      if (currentParent) currentParent.children.push({ type: 3, text })
    }
  })
  return root
}

优化阶段(Optimize)

标记静态节点和静态根节点,避免在重新渲染时重复处理。

静态节点标记

  • 通过 markStatic 递归遍历 AST,标记所有静态节点(无动态绑定或指令)。
  • 静态根节点是子节点全为静态的父节点。

关键代码

// src/compiler/optimizer.js
export function optimize(root) {
  markStatic(root)
  markStaticRoots(root)
}

function markStatic(node) {
  node.static = isStatic(node)
  if (node.type === 1) {
    node.children.forEach(child => {
      markStatic(child)
      if (!child.static) node.static = false
    })
  }
}

代码生成阶段(Generate)

将 AST 转换为可执行的渲染函数字符串。

代码生成示例: 对于 AST:

{
  tag: 'div',
  attrs: [{ name: 'id', value: '"app"' }],
  children: [{ type: 2, expression: '_s(message)', text: '{{ message }}' }]
}

生成的渲染函数代码:

with(this) {
  return _c('div', { attrs: { id: "app" } }, [_v(_s(message))])
}

关键代码

// src/compiler/codegen/index.js
export function generate(ast) {
  const code = ast ? genElement(ast) : '_c("div")'
  return `with(this){return ${code}}`
}

function genElement(el) {
  const children = genChildren(el)
  const data = genData(el)
  return `_c('${el.tag}'${data ? `,${data}` : ''}${children ? `,${children}` : ''})`
}

核心工具函数

  1. _c: 创建虚拟 DOM 节点(createElement)。
  2. _v: 创建文本节点(createTextVNode)。
  3. _s: 转换为字符串(toString)。
// src/core/instance/render-helpers/index.js
export function installRenderHelpers(target) {
  target._c = createElement
  target._v = createTextVNode
  target._s = toString
}

编译入口

通过 createCompiler 整合三个阶段:

vue compile源码实现

// src/compiler/index.js
export const createCompiler = createCompilerCreator(function baseCompile(template, options) {
  const ast = parse(template.trim(), options)
  optimize(ast, options)
  const code = generate(ast, options)
  return { ast, render: code }
})

最终生成的渲染函数可通过 new Function 实例化,供组件渲染使用。

标签: 源码vue
分享给朋友:

相关文章

vue表格重置怎么实现

vue表格重置怎么实现

重置表格数据的方法 在Vue中重置表格数据通常需要操作绑定的数据源,以下是几种常见实现方式: 直接重置数据源 // 假设表格绑定的是tableData this.tableData = [...t…

vue登录业务的实现

vue登录业务的实现

实现登录业务的基本流程 在Vue中实现登录业务通常涉及前端界面设计、表单验证、API请求交互、状态管理以及路由控制等环节。以下是核心实现步骤: 登录表单设计与验证 创建包含用户名和密码输入框的登录组…

vue 实现在线预览

vue 实现在线预览

Vue 实现在线预览的常见方法 使用 iframe 嵌入 通过 iframe 标签可以嵌入多种类型的文件,如 PDF、图片、网页等。需要确保文件地址可访问。 <template> &…

代码实现vue

代码实现vue

创建Vue项目 使用Vue CLI快速初始化项目,确保已安装Node.js和npm/yarn: npm install -g @vue/cli vue create my-vue-project c…

vue实现选区

vue实现选区

Vue 实现选区的基本方法 在Vue中实现选区功能通常涉及DOM操作和事件处理。以下是几种常见的方法: 使用原生JavaScript的Selection API 通过window.getSelec…

vue实现拍照

vue实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…