作为从 Vue 1.0 一路使用过来的开发者,Vue 3.0 并非简单的版本迭代,而是在核心架构、性能、开发体验上的全面升级,同时兼容了 2.x 的大部分核心思想,既保留了我们熟悉的开发范式,又解决了 2.x 长期存在的痛点。以下从核心架构、语法特性、性能优化、工程化等维度,结合 2.x 对比梳理关键变化。
一、核心架构:从 Options API 到 Composition API
1. Vue 2.x:Options API 为主
Vue 2.x 采用「选项式 API」,将代码按 data、methods、computed、watch、生命周期钩子 等选项划分,优点是上手简单,但存在明显痛点:
- 逻辑碎片化:一个业务逻辑(如「用户登录状态管理」)的代码会分散在
data(状态)、methods(方法)、watch(监听)、mounted(初始化)等多个选项中,组件越大,逻辑越难追踪; - 代码复用受限:mixins 是主要复用方式,但存在命名冲突、来源不清晰、逻辑依赖隐晦的问题;
- TypeScript 支持薄弱:Options API 天生不契合 TS 的类型推导,需要额外的类型声明,开发体验差。
2. Vue 3.0:Composition API(组合式 API)+ 保留 Options API
Vue 3.0 推出「组合式 API」,核心是 setup 函数(组件的入口),允许按业务逻辑维度组织代码,而非按选项类型:
<template>
<div>{{ count }}</div>
<button @click="increment">+1</button>
</template>
<script setup>
// Vue 3.0 组合式 API(<script setup> 语法糖)
import { ref, computed, onMounted } from 'vue'
// 状态定义(替代 2.x 的 data)
const count = ref(0)
// 方法定义(替代 2.x 的 methods)
const increment = () => {
count.value++
}
// 计算属性(替代 2.x 的 computed)
const doubleCount = computed(() => count.value * 2)
// 生命周期(替代 2.x 的 mounted)
onMounted(() => {
console.log('组件挂载完成,count 初始值:', count.value)
})
</script>
核心优势:
- 逻辑聚合:一个业务逻辑的所有代码(状态、方法、监听、生命周期)可集中写在一处,组件结构更清晰;
- 灵活复用:通过「组合函数(Composables)」复用逻辑(如
useUser()、useRequest()),替代 mixins,解决命名冲突和依赖问题; - 完美支持 TS:基于函数式的写法天然契合 TS 类型推导,无需额外声明即可获得完整的类型提示。
兼容说明:Vue 3.0 完全保留 Options API,2.x 的代码可直接迁移(仅需少量适配),支持「渐进式升级」—— 既可以在老组件中继续用 Options API,也可以在新组件中用 Composition API。
二、响应式系统:从 Object.defineProperty 到 Proxy
1. Vue 2.x:响应式的痛点
Vue 2.x 基于 Object.defineProperty 实现响应式,存在天然限制:
- 无法监听数组下标修改(如
arr[0] = 1)和数组长度修改(如arr.length = 0),需通过Vue.set/this.$set或数组变异方法(push/splice)触发更新; - 无法监听对象新增属性/删除属性(如
this.obj.newKey = 1),同样需要Vue.set/this.$delete; - 响应式初始化时需要递归遍历对象,性能随对象层级加深下降。
2. Vue 3.0:Proxy 重构响应式
Vue 3.0 改用 ES6 的 Proxy 实现响应式,彻底解决上述问题:
- 原生支持监听数组下标/长度修改、对象新增/删除属性,无需
$set/$delete; - 非侵入式:无需修改原对象,而是代理对象,初始化时无需递归遍历(懒代理,访问属性时才递归),性能大幅提升;
- 支持
Ref和Reactive两种响应式方式:ref:用于基础类型(字符串、数字等),通过.value访问(模板中自动解包,无需.value);reactive:用于对象/数组,返回代理对象,直接访问属性即可。
示例对比:
// Vue 2.x
export default {
data() {
return {
arr: [1, 2, 3],
obj: { name: 'Vue2' }
}
},
methods: {
updateData() {
// 无效:无法监听数组下标修改
this.arr[0] = 100
// 有效:需用 $set
this.$set(this.arr, 0, 100)
// 无效:无法监听对象新增属性
this.obj.age = 3
// 有效:需用 $set
this.$set(this.obj, 'age', 3)
}
}
}
// Vue 3.0(Composition API)
import { ref, reactive } from 'vue'
const arr = ref([1, 2, 3])
const obj = reactive({ name: 'Vue3' })
const updateData = () => {
// 有效:原生支持数组下标修改
arr.value[0] = 100
// 有效:原生支持对象新增属性
obj.age = 3
}
三、性能优化:体积、渲染、编译全方位提升
1. 体积更小
- Vue 2.x 运行时体积约 22KB(gzip);
- Vue 3.0 通过「树形摇树(Tree-shaking)」重构核心代码,仅引入使用的功能(如仅用响应式、不用编译器),最小体积约 10KB(gzip),体积减少 50% 以上。
2. 渲染更快
- 虚拟 DOM 重构:Vue 3.0 优化了虚拟 DOM 的生成和对比算法,引入「静态标记」—— 对模板中不变的节点(如纯文本、静态标签)做标记,对比时直接跳过,渲染性能提升约 55%;
- 编译优化:Vue 3.0 的模板编译器会提前分析模板结构,生成更高效的渲染函数,更新性能提升约 133%。
3. 内存占用更低
Vue 3.0 优化了组件实例的内存占用,同场景下内存使用减少约 50%。
四、其他关键变化(对比 Vue 2.x)
1. 生命周期钩子
Vue 3.0 保留了 2.x 的生命周期概念,但命名略有调整(Composition API 中),且新增 setup 替代 beforeCreate 和 created: |
Vue 2.x | Vue 3.0(Composition API) | 说明 |
|---|---|---|---|
| beforeCreate | setup(开始) | setup 执行时,组件实例未创建 | |
| created | setup(结束) | setup 执行完,组件实例已创建 | |
| beforeMount | onBeforeMount | 挂载前 | |
| mounted | onMounted | 挂载后 | |
| beforeUpdate | onBeforeUpdate | 更新前 | |
| updated | onUpdated | 更新后 | |
| beforeDestroy | onBeforeUnmount | 卸载前(命名更语义化) | |
| destroyed | onUnmounted | 卸载后(命名更语义化) |
2. 模板语法
- 支持多根节点:Vue 2.x 模板要求唯一根节点,3.0 支持多根节点(Fragment),无需包裹 `
`;
-
更灵活的 v-model:Vue 2.x 中
v-model本质是value+input事件,3.0 支持自定义绑定属性和事件,且支持多个 v-model:<!-- Vue 2.x:仅能绑定一个 v-model,且固定 value/input --> <Child v-model="name" /> <!-- Vue 3.0:支持多个 v-model,自定义属性和事件 --> <Child v-model:name="name" v-model:age="age" /> - 移除
filter:Vue 3.0 废弃了 2.x 的filter过滤器,推荐用计算属性或方法替代(减少 API 复杂度)。
3. 全局 API 调整
Vue 2.x 的全局 API(如 Vue.component、Vue.directive)会污染全局环境,3.0 改为「实例化 API」:
// Vue 2.x
import Vue from 'vue'
Vue.component('MyComponent', { /* ... */ })
Vue.directive('my-dir', { /* ... */ })
new Vue({ el: '#app' })
// Vue 3.0
import { createApp } from 'vue'
const app = createApp({ /* 根组件 */ })
app.component('MyComponent', { /* ... */ })
app.directive('my-dir', { /* ... */ })
app.mount('#app')
优势:多个 Vue 实例可独立配置,避免全局配置冲突(如多应用嵌入场景)。
4. 废弃/不推荐的特性
- 废弃
Vue.prototype:改用app.config.globalProperties挂载全局属性; - 废弃
$on/$off/$once:移除实例事件总线,推荐用第三方库(如 mitt)替代; - 不推荐
filters:用计算属性/方法替代; - 不推荐
mixins:用 Composition API 的组合函数替代。
五、迁移建议(从 Vue 2.x 到 3.0)
- 渐进式迁移:先保留 Options API,逐步在新功能中使用 Composition API,降低迁移成本;
- 工具适配:升级脚手架到 Vite(Vue 3.0 推荐)或 Vue CLI 5+,安装
@vue/compat兼容包,可临时兼容 2.x 代码; - 重点检查:
- 替换
Vue.set/$set、Vue.delete/$delete(3.0 无需); - 调整生命周期钩子(如
beforeDestroy→onBeforeUnmount); - 替换
filter为计算属性/方法;
- 替换
- TypeScript 接入:新组件建议用
<script setup lang="ts">,充分利用 3.0 的 TS 优势。
总结
- 核心架构:Vue 3.0 的 Composition API 解决了 2.x Options API 逻辑碎片化、复用难、TS 支持差的问题,同时兼容 2.x 写法,支持渐进式升级;
- 响应式系统:基于 Proxy 重构,彻底解决 2.x
Object.defineProperty无法监听数组/对象新增属性的痛点,性能和易用性大幅提升; - 性能与体验:体积更小、渲染更快,模板语法更灵活(多根节点、多 v-model),全局 API 更合理,是对 Vue 2.x 核心痛点的全面优化,同时保留了 Vue 一贯的「易用、渐进式」设计理念。
发表回复