Vue 3 不是 Vue 2 的“修补版”,而是一次从底层到上层全面重写的大版本升级。这次重写的动机很明确:解决 Vue 2 在大型项目中暴露的痛点和瓶颈,同时为未来五年的前端发展留足空间。2020 年 9 月 Vue 3 正式发布,代号“One Piece”。
为什么要重写
Vue 2 的响应式系统基于 Object.defineProperty,在设计之初并未考虑 TypeScript 和大型项目的架构需求。随着社区成长,以下问题日益突出:
- 新增/删除对象属性无法自动响应,必须用
$set/$delete - 数组的索引修改和长度变化无法追踪
- 大量组件实例创建时将整个
data对象递归代理,内存与初始化性能有优化空间 - Options API 在逻辑复用时主要靠 Mixin,容易造成命名冲突和逻辑来源不清晰
- 对 TypeScript 的支持停留在“后期修补”,类型推导不顺畅
Vue 3 的核心目标就是在保留 Vue 2 开发体验的基础上,从根本上重构响应式和渲染机制。
核心变革一:响应式系统从 Object.defineProperty 到 Proxy
这是最底层的变革。Vue 3 用 ES6 的 Proxy 代理整个对象,代替 Vue 2 对每个属性做 defineProperty。
带来的直接提升:
- 新增和删除属性自动响应:不用再记
$set和$delete,直接赋值或delete就能触发更新。 - 数组完全可用:通过索引修改元素、修改
length,都能被准确追踪。 - 性能更优:
Proxy是惰性的,只有被访问到的数据才会被递归代理,启动更快,内存占用更低。 - 支持 Map、Set 等新数据结构:响应式覆盖范围更广。
这也是为什么 Vue 3 不再支持 IE11 —— Proxy 无法被 polyfill,而 Vue 团队认为为用户提供更优质的响应式体验比兼容一个淘汰的浏览器更重要。
核心变革二:组合式 API(Composition API)
Vue 2 主要使用选项式 API(Options API),逻辑被分散在 data、methods、computed 等不同选项中。当一个组件功能复杂(比如几百行的搜索组件)时,同一块业务逻辑的相关代码被强行拆散,阅读和维护都需要在组件内反复跳转。
Vue 3 新增了组合式 API,允许在 setup 函数(或 <script setup>)中按功能聚合代码:
// 组合式 API:搜索相关的变量、逻辑写在一起
const keyword = ref('')
const results = ref([])
const handleSearch = async () => {
results.value = await fetchResults(keyword.value)
}
更关键的是,组合式 API 让逻辑复用变得极为自然:
// useMouse.js — 一个独立的逻辑模块
export function useMouse() {
const x = ref(0)
const y = ref(0)
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
// 在组件中使用
const { x, y } = useMouse()
这种按功能抽象的方式,解决了 Vue 2 中 Mixin 的命名冲突和来源模糊问题,也成为自定义 Hooks 大规模实践的起点。
核心变革三:编译与渲染性能优化
Vue 3 的编译器做了大量静态分析优化:
- 静态提升:模板中不变的部分只创建一次 VNode,后续更新直接复用。
- 动态标记(PatchFlags):每个动态节点被打上类型标记(文本、类名、属性等),Diff 时只对比对应部分,跳过无关节点。
- Block 树:将动态节点扁平化记录,避免深度递归遍历静态内容。
- 最长递增子序列用于列表 Diff,减少 DOM 移动次数。
这些优化带来的结果是:Vue 3 的更新性能通常是 Vue 2 的 1.3~2 倍,且在大型应用中差距更大,而这些优化完全由编译器自动完成,开发者无需手动干预。
核心变革四:原生 TypeScript 支持
Vue 3 本身用 TypeScript 重写,提供了完整的内置类型声明。组件的 Props、Emits、Ref 都能顺利推导类型,编辑器的智能提示和错误检查比 Vue 2 时代顺滑很多。这对大型项目而言,是代码质量和维护性的质的提升。
核心变革五:更合理的内核与生态架构
- 按需引入与 Tree Shaking:Vue 3 的 API 设计天然支持打包工具剔除无用代码,全局 API 被改为具名导出。
- 编译器与运行时分离:更利于做模板自定义编译、SSR 优化。
- Fragment:组件模板可以包含多个根节点,不必老用一个
<div>包裹。 - Teleport:将组件内容渲染到 DOM 树的任意位置(如全局弹窗)。
- Suspense:提供对异步依赖的统一加载状态处理。
Vue 2 与 Vue 3 的实用对比速览
| 维度 | Vue 2 | Vue 3 |
|------|-------|-------|
| 响应式底层 | Object.defineProperty | Proxy |
| 新增/删除属性 | 需 $set / $delete | 直接赋值/删除即可 |
| 数组响应 | 部分兼容(push/pop 等已代理) | 完全兼容(含索引、length) |
| API 风格 | Options API 为主 | Options API + Composition API 并存 |
| 逻辑复用 | Mixin(易冲突) | 自定义 Hooks(无冲突) |
| 组件根节点 | 必须单一根节点 | 允许多根节点(Fragment) |
| TypeScript | 需要额外配置和装饰器 | 原生支持,类型推导顺畅 |
| 包体积 | 约 20KB (gzip) | 约 30KB (gzip),但 Tree Shaking 更友好 |
| 渲染性能 | 中 | 快 1.3~2 倍 |
| IE 兼容 | 支持 IE11 | 不支持 IE11 |
从 Vue 2 到 Vue 3 的现状
截至 2024 年,Vue 3 已成为官方主推版本。Vue 3 同时兼容选项式 API(Options API)和组合式 API,Vue 2 的开发者可以几乎零修改地将旧代码运行在 Vue 3 的兼容模式下,再逐步将部分逻辑重构为组合式 API。第 28 章将详细讲述迁移方案。
对新人来说,现在的起始线就是 Vue 3 + 组合式 API,这是官方推荐的默认路径,也是社区生态(文档、教程、库)的主要流向。