Vue 3 设计与实现

前言:凌晨一点的源码震撼

作者 杨艺韬 · 3,132 字

前言:凌晨一点的源码震撼

写作动机

Vue 3.6 的响应式系统已经不是 3.0 那一套。打开 packages/reactivity/src/effect.ts,沿着 ref / computed / effect 这条链往下读,会发现:

  • Set-based 的依赖追踪消失了
  • 取而代之的是一套基于版本计数(version counting)的全新架构
  • 没有 Set
  • 没有 cleanup
  • 没有每次求值都要重建依赖集合的开销

这就是 Alien Signals——Vue 3.6 响应式系统的第三次重写。这本书的目的是把它讲透,不是教程式的"怎么用",而是源码级的"为什么"。

为什么在 Vue 3.6 / Vapor Mode 时代写这本书

2024 到 2026 年间,前端框架的竞争格局发生了根本性的位移。

前端军备竞赛

timeline
    title 前端框架范式转变
    2023 : React Server Components 模糊客户端/服务端
    2024 : Svelte 5 Runes 用编译器消灭运行时响应式开销
    2024 : Solid.js 证明"没有虚拟 DOM"更快
    2025 : Angular 引入 Signals 转向响应式范式
    2025 : Vue 3.6 Alien Signals + Vapor Mode 一次性颠覆两层
    2026 : 编译器觉醒时代全面到来

而 Vue,在这场军备竞赛中,做了两件足以改写历史的事:

第一件:Vapor Mode——彻底抛弃虚拟 DOM

Vapor Mode 不是对模板编译的又一次优化。它是对 Vue 底层渲染范式的根本重构

传统 Vue (VNode-based):
  模板 → render 函数 → VNode 树 → diff → patch → DOM

Vapor Mode:
  模板 → 命令序列 → 直接操作 DOM (编译期已知静态/动态边界)

在 Vapor 模式下:

  • 模板不再编译为返回虚拟节点树的 render 函数
  • 而是编译为直接操作真实 DOM 的命令序列
  • 没有 VNode,没有 patch,没有 diff
  • 编译器在编译期就确定了哪些节点是静态的、哪些绑定是动态的
  • 生成的代码只做最小量的精确更新

第二件:Alien Signals——响应式系统的第三次重写

Vue 3.0 (2020)  →  @vue/reactivity
                    基于 Set 的依赖追踪
                    ↓ 发现性能瓶颈

Vue 3.5 (2024)  →  优化版
                    引入双向链表
                    ↓ 仍有集合分配开销

Vue 3.6 (2026)  →  Alien Signals
                    基于版本计数的全新架构
                    零集合分配

每一次重写都不是"修修补补",而是对响应式核心模型的重新思考。

一个关键事实

这两件事加在一起,意味着:

如果你的 Vue 源码知识停留在 3.4 或更早,你实际上在学习一个已经被替换的系统。

市面上的 Vue 源码书籍,绝大多数基于 Vue 3.0–3.4 版本。它们讲的是基于 Set 的依赖追踪、基于 VNode 树的 patch 算法、基于 Block Tree 的编译优化。

这些知识并非没有价值——理解"旧系统为什么被替换"本身就是一种深刻的学习。但如果你想理解今天的 Vue 实际上在做什么,你需要一本基于 Vue 3.6 的书。

这本书就是为这个时刻而写的。

Alien Signals 重写响应式意味着什么

让我用一个类比来解释 Alien Signals 为什么重要。

供水系统类比

想象你管理一座城市的供水系统。

传统方案(Vue 3.0–3.4 的 Set-based tracking):

每次打开水龙头:
  系统记录 "水龙头 X 正在使用水源 A"

水源 A 水质变化:
  遍历所有记录 → 找到使用 A 的水龙头 → 逐一通知

水龙头关闭再打开:
  清除之前的记录 → 重新建立

这套系统是正确的,但有两个问题:

  1. 每次重新建立记录需要分配内存new Set()
  2. 清除旧记录本身也有开销Set.delete()

当城市规模扩大——数千个水龙头、数百个水源——这些开销就变得不可忽视了。

Alien Signals 方案

给每个水源贴一个版本号
  初始版本: 1
  水质变化: 版本号 + 1 → 2
  又一次变化: 3

每个水龙头只需要记住:
  "我上次看到的版本号是多少"

需要出水时:
  比较当前版本号与记忆中的版本号
  如果不同 → 水质变了,需要更新
  如果相同 → 什么都不用做 (O(1) 整数比较)

没有集合的分配与回收。没有遍历的开销。版本比较是 O(1) 的整数操作

范式转换

这不仅仅是"优化"。这是响应式模型的范式转换

从  基于集合的订阅-通知模型 (Push)
到  基于版本的惰性求值模型 (Pull)

🔥 深度洞察

Alien Signals 的版本计数策略,本质上是将"推模型"(Push:数据变了就通知所有依赖者)转化为"拉模型"(Pull:只有在需要求值时才检查数据是否变了)。

这一转变的哲学意义在于:最快的通知是不通知

如果一个 computed 的值在当前 tick 内没人读取,它根本不需要重新计算——即使它的依赖已经变了一百次。

这就是惰性求值的力量:只为真正被使用的值买单

量化数据

Vue 团队的基准测试表明:

指标 Vue 3.4(Set-based) Vue 3.6(Alien Signals) 提升
响应式对象创建 基准 ~-40% 内存 显著
依赖追踪开销 每次求值重建 Set 版本号比较 O(1) 数量级
大规模依赖图遍历 O(n) 遍历 + Set 操作 O(1) 版本比较 + 按需传播 显著
GC 压力 高(频繁创建/销毁 Set) 极低(无临时对象分配) 质变
大型应用首屏 基准 -15% ~ -25% 可观
深层依赖图更新 基准 -50% ~ -70% 大幅

本书与其他 Vue 书的区别

如果你在书店或网上搜索"Vue 源码"相关书籍,大致会看到三类:

类别 典型内容 读完之后你会…
API 实战书 组件开发、Pinia 状态管理、Vue Router 使用、项目实战 能熟练使用 Vue,但不知道底层发生了什么
早期源码书 Vue 3.0–3.4 源码解析、Set-based 响应式、VNode + Patch 算法 理解旧版实现,但面对 3.6 的新架构会感到陌生
本书 基于 Vue 3.6 源码,覆盖 Alien Signals、Vapor Mode、编译器全链路 理解 Vue 当前的设计、演进的动力、未来的方向

区别的核心在于:其他书基于已经被替换的实现,本书基于正在运行的现实

范式转换意味着重学

graph TD
    Old[旧范式] --> P1[Set-based 响应式]
    Old --> P2[VNode-based 渲染]

    P1 --> N1[Alien Signals<br/>版本计数]
    P2 --> N2[Vapor Mode<br/>直接 DOM 操作]

    Old -.->|知识可迁移的部分| Partial[30%]
    Old -.->|需要重学的部分| Relearn[70%]

    style Old fill:#fee2e2,stroke:#ef4444
    style N1 fill:#dcfce7,stroke:#22c55e
    style N2 fill:#dcfce7,stroke:#22c55e

用旧范式的知识去理解新系统,不仅效率低下,而且可能导致根本性的误解

本书的承诺

教科书给你答案。源码给你问题——以及回答这些问题的完整思考过程。

本书的承诺是:带你看到 Vue 3.6 每个设计决策背后的"为什么",看到被放弃的替代方案,厘清每一处权衡的得与失

无论你是否选择深入 Vue 的源码,这些响应式系统设计、编译器架构、渲染优化的经验,都可以直接迁移到你对任何前端框架的理解中。

本书读者

这本书为五类读者而写:

高级前端工程师

你已经熟练使用 Vue,但想知道:

  • v-model 的双向绑定在编译期做了什么
  • <Suspense> 的异步边界如何管理 pending 状态
  • <Teleport> 如何跨越组件树的物理边界
  • 为什么 shallowRef 在某些场景下比 ref 快 10 倍
  • 为什么 watchEffect 会自动清理副作用

本书提供的源码级解析,让你从"知其然"跨越到"知其所以然"。

框架开发者与架构师

无论你在构建自己的框架还是选型评估,Vue 3.6 的 Vapor Mode 编译策略和 Alien Signals 响应式架构都是业界前沿的设计参考。每章包含与 React、Svelte、Solid.js 的横向对比,帮你在全景中定位每个设计选择。

开源贡献者

不仅知道代码在哪里,更理解它为什么这样写。读懂 Vue 核心团队的设计意图,才能写出高质量的 PR。

技术面试备战者

"Vue 的响应式原理是什么"是高频面试题,但能精确回答 Alien Signals 版本计数机制的候选人,凤毛麟角。本书给你的不是背诵材料,而是深入到可以自信应对任何追问的理解深度。

学生与研究者

每章包含系统性的设计分析,可作为论文引用和研究参考。每章末尾的思考题覆盖概念理解、实践应用和开放讨论三个层次。

不适合的读者

❌ 寻找 "Vue 3 快速上手" 入门书
❌ 只想知道 "API 怎么用"
❌ 没有 TypeScript 基础

本书假设读者已具备 Vue 使用经验和 TypeScript 基础,想深入理解框架内部的设计与实现。

阅读路线图

本书支持多种阅读方式。你可以从第 1 章顺序通读,也可以根据自身需要选择快速路径:

路径 章节 适合 预计时间
快速精华 前言 → 1 → 3(响应式核心) → 10(Vapor) 时间有限 3-4 小时
响应式深潜 1 → 3 → 4 → 5 → 6 Alien Signals 爱好者 10-15 小时
编译器之旅 1 → 11 → 12 → 13 → 10 编译器方向 12-18 小时
全栈通读 1 → 2 → 3 → … → 13 系统性建立认知 40-60 小时
面试突击 1 → 3 → 9(diff) → 10(Vapor) 面试准备 6-8 小时

阅读建议

工程师建议顺序通读,每章旁边打开 Vue 源码,边读边探索。

急性子直接翻到第 3 章,从 Alien Signals 的第一行代码开始。

面试者优先看 ch03(响应式)、ch09(diff/patch)、ch10(Vapor)——这三章覆盖 80% 的高频面试题。

每一章的写作节奏

每一章都遵循同样的节奏:

graph LR
    A[设计意图<br/>为什么需要这个] --> B[架构图<br/>系统全景]
    B --> C[源码精读<br/>逐行解析]
    C --> D[横向对比<br/>React/Svelte/Solid]
    D --> E[实战启示<br/>日常使用影响]
    E --> F[思考题<br/>3 个难度]

    style A fill:#dbeafe,stroke:#3b82f6
    style C fill:#dcfce7,stroke:#22c55e
    style F fill:#fef3c7,stroke:#f59e0b
  1. 设计意图——这一章要解决什么问题
  2. 架构图——系统全景
  3. 源码精读——逐行解析关键代码
  4. 横向对比——和其他框架的类似设计对照
  5. 实战启示——日常使用 Vue 时的影响
  6. 思考题——概念 / 实践 / 开放讨论三层次

源码与约定

本书基于 Vue 3.6.x 版本(具体以各章标注的 commit hash 为准)。核心架构模式演化缓慢——即使代码持续迭代,书中的设计思想仍然适用。

代码约定

所有代码示例均从 Vue 源码中提取,标注对应的文件路径。部分代码为可读性做了适度简化,遵循以下约定:

标记 含义
// ... 省略与当前讨论无关的代码
// ← 关键 标注当前讨论的核心逻辑
// ⚠️ 注意 标注容易踩坑的地方
// 💡 洞察 标注值得深思的设计决策
  • TypeScript:所有示例使用 TypeScript,与 Vue 源码保持一致
  • 简化导入:省略明显的 import 语句,避免视觉噪音

源码仓库

git clone https://github.com/vuejs/core.git
cd core
git checkout v3.6.0  # 切换到本书对应版本
pnpm install
pnpm build            # 构建所有包

建议在阅读每章时,始终在编辑器中打开对应的源码文件。源码是本书最重要的"配图"

目录速查

packages/
├── reactivity/       # ch03-06 响应式系统(Alien Signals)
├── runtime-core/     # ch07-09 运行时核心(setup/h/diff)
├── runtime-dom/      # ch10 DOM 运行时
├── runtime-vapor/    # ch10 Vapor Mode 运行时
├── compiler-core/    # ch11-12 编译器核心
├── compiler-dom/     # ch11 DOM 编译器
├── compiler-vapor/   # ch13 Vapor 编译器
├── compiler-sfc/     # ch12 单文件组件编译
└── vue/              # 对外发布的聚合包

配套资源

致谢

感谢尤雨溪和 Vue 核心团队——书中剖析的每个设计决策都建立在他们的公开工作之上。

感谢 Johnson Chu——Alien Signals 的作者。Vue 3.6 的响应式重写建立在他的工作之上。


杨艺韬 2026 年春,北京