Vue2 与 Vue3 对比 + 核心差异

Vue2(2016 年发布)和 Vue3(2020 年 9 月发布,代号 One Piece)是 Vue 框架的两大核心版本,Vue3 是 Vue2 的重写升级版,并非简单的迭代,底层源码、核心架构、API 设计都做了颠覆性重构。

Vue3 完全兼容大部分 Vue2 的语法,目的是解决 Vue2 中暴露的核心痛点(比如响应式缺陷、大型项目性能、TypeScript 支持、组合式代码复用等),同时保留了 Vue 最核心的「渐进式、易用性」优势。

当下前端开发的现状:新项目首选 Vue3,老项目维护 Vue2,Vue2 目前处于「维护模式」(仅修复 bug,无新功能),Vue 官方团队的所有精力都投入到 Vue3 生态建设中。

补充你上一篇的 Pinia/Vuex 关联:Vue2 生态标配 Vuex3 ,Vue3 官方推荐 Pinia(Vuex5 的最终形态),Vuex4 仅为 Vue3 的过渡方案。


一、Vue2 与 Vue3 核心定位 & 生命周期

✅ 版本基础信息

  1. Vue2 :最新稳定版 2.7.x,最后一个支持 Options API 的版本,也叫「经典版 Vue」,易学易用,生态成熟,文档完善。
  2. Vue3 :最新稳定版 3.4.x,基于 Proxy 重构,支持 Options API + Composition API 双语法,体积更小、性能更强、TS 友好,是未来的主流。
  3. 兼容性:Vue2 兼容 IE11,Vue3 放弃 IE 浏览器,仅支持现代浏览器(Chrome/Firefox/Edge 等)。

✅ 生命周期钩子函数(核心变化,必记)

Vue3 完全兼容 Vue2 的大部分生命周期钩子 ,只是改名 2 个、废弃 1 个,且新增了组合式 API 的写法,执行顺序完全一致,核心生命周期的逻辑不变。

🔥 相同的生命周期(无变化,直接复用)
  • 创建阶段:beforeCreatecreated
  • 更新阶段:beforeUpdateupdated
  • 销毁阶段:activateddeactivated(keep-alive 专属)
🔥 已改名的生命周期(Vue2 → Vue3,必须改)

核心原因:Vue3 中「销毁」的语义变更为「卸载」,更贴合组件的渲染逻辑

  1. beforeDestroybeforeUnmount
  2. destroyedunmounted
🔥 已废弃的生命周期(Vue3 中彻底移除)

Vue2$destroy 方法被废弃,Vue3 中不再支持手动调用组件销毁方法,组件卸载由框架统一管理。

✅ 生命周期对比表(最常用,建议收藏)
Vue2 生命周期钩子 Vue3 生命周期钩子 执行时机 & 作用
beforeCreate beforeCreate 实例创建前,数据 / 方法未初始化,极少用
created created 实例创建完成,数据 / 方法已挂载,可发起异步请求
beforeMount beforeMount 挂载前,模板已编译,DOM 未生成
mounted mounted 挂载完成,DOM 已渲染,可操作 DOM,最常用
beforeUpdate beforeUpdate 数据更新前,DOM 未重新渲染
updated updated 数据更新完成,DOM 已重新渲染
beforeDestroy beforeUnmount 组件卸载前,可做清理工作(清除定时器、解绑事件)
destroyed unmounted 组件卸载完成,所有监听、事件全部销毁

二、Vue2 与 Vue3 核心语法差异(高频考点,全是重点)

✅ 1. 入口创建方式不同(new Vue () → createApp ())

✔ Vue2 创建根实例(全局挂载,污染全局)

Vue2 通过 new Vue({}) 创建全局 Vue 实例,所有的全局配置(全局组件、全局指令、全局方法)都挂载在这个实例上,本质是全局单例模式,存在全局污染的问题。

js

复制代码
// Vue2 main.js 入口文件
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
// 全局挂载
new Vue({
  render: h => h(App)
}).$mount('#app')

// 全局注册组件/指令,挂载在Vue构造函数上
Vue.component('MyBtn', MyBtn)
Vue.directive('focus', focusDirective)
✔ Vue3 创建根实例(链式调用,无全局污染)

Vue3 彻底重构了入口逻辑,通过 createApp() 创建独立的应用实例 ,所有全局配置都挂载在「当前应用实例」上,不同应用实例之间互不影响,完美解决全局污染问题,且支持链式调用,写法更优雅。

js

复制代码
// Vue3 main.js 入口文件
import { createApp } from 'vue' // 按需导入 createApp
import App from './App.vue'

// 创建应用实例 + 链式调用 + 挂载,无全局污染
createApp(App)
  .component('MyBtn', MyBtn) // 仅当前应用生效
  .directive('focus', focusDirective)
  .mount('#app')

✅ 2. 响应式原理的彻底重构(最核心底层差异,必懂)

这是 Vue2 和 Vue3 最本质的区别,也是 Vue3 性能碾压 Vue2 的核心原因,两者的响应式实现方案完全不同,解决的问题也不同。

✔ Vue2 的响应式:基于 Object.defineProperty() 实现
✅ 实现原理

遍历 data 中的所有属性,通过 Object.defineProperty() 为每个属性添加 getter/setter,拦截属性的「读取」和「修改」,从而实现数据劫持,依赖收集和派发更新。

❌ Vue2 响应式的天生缺陷(无法解决)
  1. 无法监听对象的新增 / 删除属性 :比如 this.obj.name = '张三' 新增属性,delete this.obj.age 删除属性,Vue2 监听不到,页面不会更新。
  2. 无法监听数组的下标修改和长度修改 :比如 this.arr[0] = 100this.arr.length = 0,Vue2 监听不到。
  3. 解决方案:必须手动调用 Vue.set(target, key, value)this.$set() 才能触发更新,非常繁琐。
✔ Vue3 的响应式:基于 ES6 Proxy + Reflect 实现
✅ 实现原理

通过 Proxy 代理整个对象 / 数组,通过 Reflect 操作原对象的属性,实现对「整个对象」的劫持,而非单个属性。

✅ Vue3 响应式的核心优势(完美解决 Vue2 的痛点)
  1. 可以监听对象的新增 / 删除属性:无需手动调用任何方法,直接赋值 / 删除属性即可触发页面更新。
  2. 可以监听数组的下标修改、长度修改、数组方法this.arr[0] = 100this.arr.length = 0this.arr.push(1) 都能被监听。
  3. 支持 Map/Set/WeakMap/WeakSet 等原生集合类型的响应式,Vue2 完全不支持。
  4. 性能更高:Proxy 是浏览器原生支持的 API,劫持效率远高于 Object.defineProperty(),且 Vue3 的响应式是惰性劫持,用到的属性才会被劫持,大型项目性能提升明显。

✨ 结论:Vue3 的响应式是真正的「全量响应式」,Vue2 是「部分响应式」

✅ 3. 核心语法:Options API(Vue2) vs Composition API(Vue3)

这是 Vue2 和 Vue3 最直观的语法差异 ,也是开发方式的分水岭,Vue3 并没有抛弃 Vue2 的 Options API,而是新增了 Composition API,支持「双语法并存」,这也是 Vue 的「渐进式」体现。

✔ Vue2 主推:Options API(选项式 API)
✅ 写法特点

把组件的逻辑拆分为固定的选项data、methods、computed、watch、生命周期钩子 等,所有代码按选项分类书写。

vue

复制代码
<!-- Vue2 Options API 写法 -->
<template>
  <div>{{ count }}</div>
  <button @click="add">点击+1</button>
</template>

<script>
export default {
  data() {
    return { count: 0 } // 数据写在data里
  },
  methods: {
    add() { this.count++ } // 方法写在methods里
  },
  computed: {
    doubleCount() { return this.count * 2 } // 计算属性写在computed里
  },
  mounted() { console.log('挂载完成') } // 生命周期写在根层级
}
</script>
✅ 优点
  • 入门门槛极低,学习成本小,适合新手和小型项目。
  • 代码结构清晰,按选项分类,一目了然。
❌ 缺点(Vue2 的核心痛点)
  • 代码碎片化:当组件逻辑复杂时,一个功能的「数据、方法、监听」会分散在不同的选项中,比如一个「登录功能」的 data、methods、watch 会分开写,需要上下滚动代码才能看懂完整逻辑,维护成本极高。
  • 代码复用困难:只能通过「混入 mixins」复用代码,但 mixins 有命名冲突、逻辑溯源困难的问题,大型项目中极易出现混乱。
  • TypeScript 支持差:Options API 的写法天生和 TS 不兼容,需要大量的类型声明,开发体验极差。
✔ Vue3 主推:Composition API(组合式 API)
✅ 写法特点

Vue3 新增的 setup() 函数是 Composition API 的入口 ,所有的「数据、方法、计算属性、监听、生命周期」都可以写在 setup() 里,一个功能的所有逻辑可以聚合在一起书写,彻底解决代码碎片化问题。

vue

复制代码
<!-- Vue3 Composition API 写法 -->
<template>
  <div>{{ count }}</div>
  <button @click="add">点击+1</button>
</template>

<script setup>
// 按需导入需要的API,体积更小
import { ref, computed, onMounted } from 'vue'

// 响应式数据
const count = ref(0)

// 方法
const add = () => { count.value++ }

// 计算属性
const doubleCount = computed(() => count.value * 2)

// 生命周期钩子(组合式写法,前缀on)
onMounted(() => { console.log('挂载完成') })
</script>
✅ 核心优势(Vue3 的灵魂)
  1. 逻辑聚合:一个功能的所有代码都写在一起,比如「购物车加减」的 count、add、reduce、computed 都在一块,不用滚动代码,可读性拉满。
  2. 代码复用极致友好 :可以把逻辑抽离成独立的组合式函数(Composables) ,比如把「请求数据」的逻辑抽成 useRequest(),在任意组件中导入复用,无命名冲突,逻辑溯源清晰。
  3. 完美支持 TypeScript:Composition API 的写法和 TS 的语法完全契合,类型推导零成本,无需额外声明,大型项目必备。
  4. 按需导入:需要什么 API 就导入什么,打包体积更小,性能更高。

✨ 官方态度:Vue3 中 Options API 完全可用,Vue2 的代码可以无缝迁移到 Vue3,只是 Composition API 是未来的主流,推荐新项目使用。


三、常用 API 的语法变更(高频使用,必记)

✅ 1. data 定义方式

  • Vue2:必须是函数返回对象的形式(组件复用防止数据污染)。
  • Vue3:Options API 写法和 Vue2 一致;Composition API 用 ref() 定义基本类型,reactive() 定义引用类型。

✅ 2. 父子组件传参(props/emits,核心变更:emits 必须声明)

✔ 父传子(props):无变化,完全兼容

Vue2 和 Vue3 的 props 接收、校验、默认值写法完全一致,只是 Vue3 中 props 可以在 setup 中通过解构获取。

✔ 子传父($emit):Vue3 新增「emits 声明」(必做)

Vue2 中子组件可以直接调用 this.$emit('事件名', 参数),无需提前声明,容易出现拼写错误,且无法校验事件参数。Vue3 中推荐(强烈建议) 在组件的 emits 选项中声明所有要触发的事件,好处:

  1. 代码可读性更高,一眼看出组件向外暴露的事件;
  2. 可以校验事件的参数类型;
  3. 避免和原生事件重名(比如 click)。

vue

复制代码
<!-- Vue3 子组件 -->
<script setup>
// 方式1:setup语法糖,直接声明emits
const emit = defineEmits(['add', 'delete'])
// 触发事件
emit('add', 10)

// 方式2:带参数校验的声明
const emit = defineEmits({
  add: (num) => typeof num === 'number', // 校验参数是数字
  delete: () => true
})
</script>

✅ 3. 全局 API 的迁移:Vue.xxxapp.xxx

Vue2 中所有的全局 API 都是挂载在 Vue 构造函数上,Vue3 中所有的全局 API 都迁移到了 createApp() 创建的应用实例上,避免全局污染,比如:

  • Vue2:Vue.component() → Vue3:app.component()
  • Vue2:Vue.directive() → Vue3:app.directive()
  • Vue2:Vue.filter() → ✅ Vue3 彻底移除过滤器 filter

✅ 4. 过滤器 filter 被彻底移除(Vue3 重大变更)

Vue2 中的 filter 是常用的格式化数据的方式,比如格式化时间、金额,但 Vue3 中完全移除了 filter,官方给出的替代方案:

  1. 计算属性 computed 替代(推荐,适合组件内使用);
  2. 全局方法替代(适合全局复用,比如格式化时间);
  3. 组合式函数替代(适合复杂的格式化逻辑)。

✅ 5. v-model 指令的重大优化(Vue3 更灵活)

Vue2 中一个组件只能绑定一个 v-model ,且默认绑定的是 value 属性和 input 事件,自定义组件中使用 v-model 需要写 model 选项,非常繁琐。Vue3 中彻底重构 v-model,支持:

  1. 一个组件可以绑定多个 v-model
  2. 无需写 model 选项,直接通过 v-model:属性名 绑定;
  3. 支持自定义修饰符,比如 v-model.trimv-model:age.number

✅ 6. watch 监听的语法变更

  • Vue2:watch 是选项式 API,写在组件根层级,只能监听 data 中的属性。
  • Vue3:Composition API 中用 import { watch } from 'vue' 按需导入,支持监听ref、reactive、计算属性、数组、对象 ,写法更灵活,还新增了 watchEffect(自动监听依赖)。

四、Vue2 与 Vue3 生态对比(选型必看)

✅ 状态管理:Vuex3 → Pinia(Vuex5)

  • Vue2 标配:Vuex3(5 大核心:State、Getter、Mutation、Action、Module);
  • Vue3 官方推荐:Pinia(Vuex5 的最终形态,3 大核心:State、Getter、Action),彻底移除 Mutation,Action 支持同步 / 异步,TS 友好,模块化更优雅,体积更小。

补充:Vue3 也支持 Vuex4,但 Vuex4 只是 Vuex3 的 Vue3 适配版,无核心功能更新,官方已明确 Pinia 是未来。

✅ 路由管理:VueRouter3 → VueRouter4

  • Vue2 标配:VueRouter3;
  • Vue3 标配:VueRouter4,API 基本兼容,新增了组合式 API 的写法(useRoute()useRouter())。

✅ UI 组件库

  • 适配 Vue2:ElementUI、Vant2、Ant Design Vue1.x、ElementUI-Plus(兼容版);
  • 适配 Vue3:Element Plus、Vant4、Ant Design Vue4.x、Naive UI、Vuestic UI;

五、Vue2 项目迁移到 Vue3 的建议(实用指南)

✅ 方案 1:平滑过渡(推荐,低成本)

Vue 官方提供了 Vue2.7 版本 ,这是 Vue2 的最后一个版本,内置了 Vue3 的 Composition API ,可以在 Vue2 项目中直接使用 setup()ref()reactive() 等 Vue3 的语法,无需重构项目,先体验 Vue3 的特性,后续再逐步迁移。

✅ 方案 2:渐进式重构(适合中大型项目)

  1. 先把 Vue2 项目的依赖升级到兼容 Vue3 的版本;
  2. 新增的业务模块用 Vue3 的 Composition API 开发;
  3. 老的业务模块继续用 Vue2 的 Options API 维护;
  4. 逐步将老模块重构为 Vue3 语法,无风险、低成本。

✅ 方案 3:全新重构(适合小型项目 / 新项目)

直接基于 Vue3 + Vite + Pinia + TypeScript 搭建新项目,这是目前最主流的技术栈,开发体验和性能都拉满。


六、核心总结 & 选型建议(精华)

✅ 核心差异一句话总结

Vue3 是 Vue2 的全面升级版 ,解决了 Vue2 的所有核心痛点,同时保留了 Vue 的易用性,性能更强、语法更灵活、生态更完善、TS 更友好

✅ 选型建议(无争议,行业共识)

  1. 新项目 :毫不犹豫选 Vue3 + Vite + Pinia + Composition API,这是未来的主流,也是 Vue 官方的主推方向。
  2. 老项目 :继续维护 Vue2,无需强行重构,Vue2 的生态足够稳定,能满足业务需求;如果需要新增功能,可以升级到 Vue2.7,使用 Composition API 开发新功能。
  3. 团队技术栈:如果团队需要强类型支持(大型项目),必须选 Vue3;如果是小型项目、快速迭代,Vue2 和 Vue3 都可以,Vue2 的入门成本更低。

✅ 学习建议

  1. 如果你是Vue 新手 :直接学 Vue3,无需再学 Vue2,Vue3 的语法更先进,学习成本和 Vue2 差不多,学会 Vue3 可以无缝兼容 Vue2 的语法。
  2. 如果你已经会 Vue2:只需重点学习 Composition API、响应式原理、生命周期改名、API 迁移 这几个点,1-2 天就能上手 Vue3。

希望这篇全面的对比能帮你彻底理清 Vue2 和 Vue3 的差异,从语法到生态一网打尽,无论是面试还是开发都够用啦!👍

👉 **觉得有用的点点关注谢谢~**

相关推荐
tiandyoin2 小时前
给 MHTML 添加滚动条.mhtml
前端·chrome·html·mhtml
遗憾随她而去.2 小时前
前端大文件上传(切片并发/断点续传/秒传/WebWorker 计算Hash) 含完整代码
前端
风叶悠然2 小时前
vue3中pinia的数据持久化
vue.js
AKA__老方丈3 小时前
vue-cropper图片裁剪、旋转、缩放、实时预览
前端·vue.js
梦6504 小时前
Vue 单页面应用 (SPA) 与 多页面应用 (MPA) 对比
前端·javascript·vue.js
清铎4 小时前
大模型训练_week3_day15_Llama概念_《穷途末路》
前端·javascript·人工智能·深度学习·自然语言处理·easyui
岛泪4 小时前
把 el-cascader 的 options 平铺为一维数组(只要叶子节点)
前端·javascript·vue.js
Kiyra5 小时前
阅读 Netty 源码关于 NioEventLoop 和 Channel 初始化部分的思考
运维·服务器·前端
冰暮流星5 小时前
javascript的switch语句介绍
java·前端·javascript