当前位置:首页 > 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 整合三个阶段:

// 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 compile源码实现

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

相关文章

vue怎么实现动画

vue怎么实现动画

Vue 动画实现方法 Vue 提供了多种方式实现动画效果,包括内置过渡系统、第三方库集成以及 CSS 动画。以下是常见实现方法: 使用 Vue 过渡系统 通过 <transition>…

vue实现防抖节流

vue实现防抖节流

Vue 中实现防抖(Debounce) 防抖的核心是延迟执行函数,在连续触发时取消前一次的调用,只执行最后一次。适用于输入框搜索、窗口大小调整等场景。 方法1:使用 Lodash 的 _.debou…

vue实现单点

vue实现单点

Vue 实现单点登录(SSO)方案 单点登录(SSO)允许用户在多个相关但独立的系统中使用同一组凭证登录。以下是基于 Vue 的实现方案: 基于 OAuth2/OpenID Connect 的实现…

vue  select实现

vue select实现

Vue Select 实现方法 在 Vue 中实现下拉选择功能可以使用原生 <select> 标签或第三方库如 vue-select。以下是两种方法的详细说明: 原生 HTML Sel…

代码实现vue

代码实现vue

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

vue交互实现

vue交互实现

Vue 交互实现方法 Vue.js 提供了多种方式实现用户交互,包括事件处理、表单绑定、动态渲染等。以下是常见的交互实现方法: 事件处理 通过 v-on 或 @ 指令绑定事件,触发方法或直接执行表…