1.vue2和vue3的区别
1. 响应式系统重构
| 特性 |
Vue 2 |
Vue 3 (Composition API) |
| 实现原理 |
Object.defineProperty |
Proxy |
| 响应式缺陷 |
无法检测对象/数组的增删 |
支持深层响应式,无死角监听 |
| 性能开销 |
递归遍历全对象,初始化慢 |
惰性代理,按需触发 |
| 代码示例 |
data() { return { obj: {} } } |
const obj = reactive({}) |
2. Composition API
| 场景 |
Vue 2 (Options API) |
Vue 3 (Composition API) |
| 逻辑组织 |
按选项类型分离(data/methods) |
按功能聚合(一个功能集中写) |
| 复用方式 |
Mixins(命名冲突风险) |
自定义 Hook(useXxx) |
| TS 支持 |
类型推断较弱 |
完美支持泛型、类型推导 |
| 代码示例 |
methods: { fetchData() {} } |
const { data } = useFetch() |
3. 性能提升
| 指标 |
Vue 2 |
Vue 3 |
| 打包体积 |
22.5KB (min+gzip) |
10KB (min+gzip) 减少 55% |
| 虚拟 DOM |
全量 Diff |
静态标记 + PatchFlag 优化 |
| 编译时优化 |
无 |
Block Tree / 静态提升 |
| 内存占用 |
高(每个组件实例开销大) |
低(更高效的组件初始化) |
4. 模板变化
| 语法 |
Vue 2 |
Vue 3 |
| 片段支持 |
必须单根节点 |
支持多根节点 |
| v-model |
1 组件仅 1 个 v-model |
可多个 v-model:propName |
| Key 修饰符 |
仅限 v-on |
支持所有指令(如 v-model.trim) |
| 代码示例 |
<template><div>...</div></template> |
<template><header/> <main/></template> |
5. TypeScript 支持
| 能力 |
Vue 2 |
Vue 3 |
| 类型定义 |
需手动扩展 @vue/runtime-core |
内置完整 TS 类型 |
| Props 类型 |
基于运行时校验 |
编译时静态类型检查 |
| 泛型组件 |
不支持 |
支持(如 defineComponent<Props>()) |
开发体验:Vue 3 + Volar 插件可实现与 React + TypeScript 同级别的类型安全。
6. 生命周期对照
| Vue 2 |
Vue 3 (Composition API) |
beforeCreate |
改用 setup() |
created |
改用 setup() |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestroy |
onBeforeUnmount |
destroyed |
onUnmounted |
特点
- 直接操作对象的属性,无需
.value。
- 不支持重新赋值整个对象(会失去响应式)。
3. 核心区别
| 特性 |
ref() |
reactive() |
| 数据类型 |
基本类型或对象/数组 |
仅限对象/数组 |
| 访问方式 |
需用 .value |
直接访问属性 |
| 重新赋值 |
支持(通过 .value) |
不支持(会破坏响应式) |
| 模板解包 |
自动解包(无需 .value) |
无需解包 |
| 适用场景 |
简单数据或需要重新赋值的场景 |
复杂对象或嵌套数据 |
4. 如何选择?
-
用 ref 当:
- 数据是基本类型(如
string、number)。
- 需要重新赋值整个对象/数组。
- 在组合式函数中返回响应式数据。
-
用 reactive 当:
- 数据是复杂对象或嵌套结构。
- 需要直接操作属性(如
state.user.name)。
- 逻辑上需要聚合多个相关属性