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)。 - 逻辑上需要聚合多个相关属性