Vue模板源码解析:从HTML到渲染函数

2026-09-30 0 202

Vue模板源码解析:从HTML到渲染函数

Vue模板不是直接操作DOM,而是编译成渲染函数。本文拆解模板编译三阶段:解析生成AST、优化静态节点、生成代码,并说明with语句与作用域提升如何影响运行时性能。

Vue,模板编译,AST,渲染函数,源码

模板不是魔法,是编译

Vue 的模板语法写起来像 HTML,但浏览器不认识 v-if 和 {{ }}。真正发生在背后的事是:模板被编译成 渲染函数,执行后返回虚拟 DOM。

理解这一步,能解释很多“为什么不能写复杂表达式”“为什么 v-if 和 v-for 不推荐同级”的问题。

编译入口:$mount 做了什么

以完整版 Vue 为例,$mount 里会判断是否存在 render 函数。没有就走进 compileToFunctions。核心调用链是 baseCompile(template, options),它返回 { ast, render, staticRenderFns }。

三阶段拆解

解析:HTML 变成 AST

解析器用正则和栈结构逐字符扫描模板。遇到开始标签就 elementStack.push,遇到结束标签就配对弹出。属性解析会区分普通属性、指令(v- 前缀)和修饰符。

最终得到一棵 AST 节点树,每个节点携带 tag、attrsList、children、parent 等字段。注意:AST 是编译中间产物,不在运行时存在。

优化:标记静态节点

optimize(ast, options) 遍历 AST,给永远不变的节点打上 static: true。判断标准很严格:节点本身无动态绑定,且所有子节点都是静态的。

被标记的静态节点在后续 patch 中会被 跳过 diff,这是 Vue 性能优于“全量对比”的关键之一。静态根节点还会被提取到 staticRenderFns 数组,避免每次渲染重新创建。

生成:AST 转代码字符串

generate(ast, options) 递归遍历,调用 genElement 拼出类似这样的字符串:

with(this){return c(‘div’,{attrs:{“id”:”app”}},[v(“hello”)])}

c 是 createElement,v 是 createTextVNode。生成的是字符串,再通过 new Function(code) 变成可执行函数。

with 的争议与替代

with(this) 让模板里的变量直接映射到组件实例,写起来简洁。但它使作用域链变长,且严格模式下不可用。

Vue 3 移除了 with,改用 代理对象 + 手动作用域提升。通过 _ctx 显式访问,并把静态提升的节点缓存在渲染函数外部。这是编译策略的一次重要演进。

编译时与运行时的边界

明白这条边界,就知道:

  • 模板里的表达式无法访问 window,因为 with 只绑定组件实例;
  • v-if 优先级低于 v-for 在 Vue 2 中成立,Vue 3 调整了顺序;
  • 大量静态内容不会拖慢更新,因为它们在编译时就被标记并跳过。

读模板源码的收益,不是背下函数名,而是建立“模板→AST→代码→渲染函数”的完整心智模型。下次遇到渲染性能问题,你会知道该往编译产物里看一眼。

看过这篇文章的人,推荐看以下内容

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

版权声明:所有的源码、软件和资料,不得使用于非法商业用途,不得违反国家法律,一切关于该资源商业行为与本站无关。

影子cms 站长学院 Vue模板源码解析:从HTML到渲染函数 https://www.yingzicms.com/6093.html

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务