Vue2 与 Vue3 的详细区别

星期五, 7月 3, 2026 | 3分钟阅读 | 更新于 星期五, 7月 3, 2026

@

公司老项目用 Vue2,新项目要上 Vue3。Vue3 不只是版本号变了,从响应式原理到 API 风格都有重写。本文系统对比两者的差异,方便迁移和理解。

一、响应式原理(最核心的区别)

这是 Vue2 和 Vue3 性能差异的根源。

Vue2:Object.defineProperty

// Vue2 的响应式本质
Object.defineProperty(obj, 'key', {
  get() { /* 收集依赖 */ },
  set() { /* 触发更新 */ }
})

痛点

  1. 无法监测新增/删除属性this.obj.newProp = 1 不会触发更新,必须用 this.$set
  2. 无法监测数组下标修改this.arr[0] = 1 不生效,要用 Vue.setsplice
  3. 深度监听要一次性递归:对象初始化时就把所有层级遍历一遍,性能差

Vue3:Proxy

// Vue3 的响应式本质
const proxy = new Proxy(target, {
  get(target, key) { /* 收集依赖 */ },
  set(target, key, value) { /* 触发更新 */ }
})

优势

  1. 监测新增/删除属性:直接 obj.newProp = 1 就能触发,告别 $set
  2. 数组下标修改生效arr[0] = 1 正常工作
  3. 惰性响应式:访问到哪一层才代理哪一层,初始化快
  4. 能监测 Map/Set/WeakMap 等新数据结构

二、API 风格

Vue2:Options API(选项式)

<script>
export default {
  data() {
    return { count: 0, name: '张三' }
  },
  computed: {
    double() { return this.count * 2 }
  },
  methods: {
    increment() { this.count++ }
  },
  mounted() {
    console.log('组件挂载')
  }
}
</script>

特点:datamethodscomputed、生命周期分散在不同选项里。同一个逻辑的代码被拆得到处都是。

Vue3:Composition API(组合式)

<script setup>
import { ref, computed, onMounted } from 'vue'

const count = ref(0)
const name = ref('张三')
const double = computed(() => count.value * 2)

function increment() {
  count.value++
}

onMounted(() => {
  console.log('组件挂载')
})
</script>

特点:

  • <script setup> 语法糖,不用写 export default
  • 相关逻辑写在一起,方便提取成自定义 Hook
  • 没有 this,避免 this 指向混乱的问题

提取逻辑复用

Vue2:用 mixin,但 mixin 有命名冲突、来源不清晰的问题。

Vue3:自定义 Hook,清晰且无冲突:

// useCounter.js
import { ref } from 'vue'
export function useCounter(initial = 0) {
  const count = ref(initial)
  const increment = () => count.value++
  return { count, increment }
}

// 组件中使用
const { count, increment } = useCounter(10)

三、响应式 API 对比

功能Vue2Vue3
简单变量响应式放 data 里ref()
对象响应式放 data 里reactive()
计算属性computed: {}computed(() => ...)
监听watch: {}watch() / watchEffect()
修改值this.count++count.value++(ref)

ref vs reactive

import { ref, reactive } from 'vue'

// ref:用于基本类型,.value 访问
const count = ref(0)
count.value++

// reactive:用于对象,直接访问
const state = reactive({ name: '张三', age: 20 })
state.age++

注意reactive 不能整体替换,state = newObj 会丢失响应式。要替换整体用 ref

四、其他重要变化

1. 多根节点(Fragment)

Vue2 模板必须有单一根节点:

<!-- Vue2报错 -->
<template>
  <div>1</div>
  <div>2</div>
</template>

<!-- Vue2必须包一层 -->
<template>
  <div>
    <div>1</div>
    <div>2</div>
  </div>
</template>

Vue3 支持多根节点:

<!-- Vue3可以 -->
<template>
  <div>1</div>
  <div>2</div>
</template>

2. Teleport(传送门)

把组件渲染到 DOM 树的其他位置,比如弹窗渲染到 body:

<Teleport to="body">
  <div class="modal">弹窗内容</div>
</Teleport>

3. 生命周期变化

Vue2Vue3 (setup)
beforeCreate(setup 本身)
created(setup 本身)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted

注意 destroyed 改名为 unmounted

4. v-model 变化

<!-- Vue2 -->
<MyInput v-model="value" />
<!-- 等价于 -->
<MyInput :value="value" @input="value = $event" />

<!-- Vue3默认用 modelValue -->
<MyInput v-model="value" />
<!-- 等价于 -->
<MyInput :modelValue="value" @update:modelValue="value = $event" />

<!-- Vue3 还支持多个 v-model -->
<MyInput v-model:name="name" v-model:age="age" />

5. 全局 API 变化

// Vue2
Vue.component('MyComp', {})
Vue.use(MyPlugin)
new Vue({ render }).$mount('#app')

// Vue3:改为应用实例
const app = createApp({})
app.component('MyComp', {})
app.use(MyPlugin)
app.mount('#app')

好处:多个应用实例互不干扰。

五、性能与体积

指标Vue2Vue3
包体积较大减少 ~40%
首次渲染-快 ~100%
更新渲染-快 ~50%
内存占用-减少 ~50%
Tree-shaking不支持支持(按需引入)

Vue3 用 TypeScript 重写,类型支持更好,且支持 Tree-shaking —— 没用到的 API 不会打包进去。

六、生态系统

工具Vue2Vue3
构建Vue CLI (webpack)Vite(推荐)/ Vue CLI
路由vue-router 3vue-router 4
状态管理VuexPinia(推荐)/ Vuex 4
IDE 支持VeturVolar
UI 库Element UIElement Plus / Naive UI

Pinia 是 Vue3 官方推荐的状态管理,比 Vuex 简单很多:

// Pinia store
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
})

没有 mutations,直接修改 state,TypeScript 支持也更好。

七、迁移建议

新项目

直接用 Vue3 + Vite + Pinia,没有任何理由用 Vue2。

老项目迁移

  1. 不必一次性全迁:Vue3 提供了 @vue/compat 迁移构建版本,可以渐进迁移
  2. 优先迁大组件:把逻辑复杂的组件用 Composition API 重写
  3. 工具链先行:Vetur → Volar,Vue CLI → Vite
  4. 第三方库检查:确认 Element UI 等依赖是否有 Vue3 版本

Vue3 兼容选项式 API

好消息:Vue3 仍然支持 Options API。如果团队短期不适应,可以先用 Options API,逐步过渡到 Composition API。

总结

Vue2 → Vue3 的核心变化:

维度Vue2Vue3
响应式definePropertyProxy
API 风格Options APIComposition API
根节点单一根Fragment 多根
构建Vue CLIVite
状态VuexPinia
类型TypeScript 重写

一句话总结:Vue3 用 Proxy 解决了 Vue2 的响应式缺陷,用 Composition API 解决了逻辑复用难题,整体更现代、更快、类型更友好。 新项目无脑选 Vue3。

© 2026 My Blog

🌱 Powered by Hugo with theme Dream.