Vue 2 升级到 Vue 3 是底层机制、开发范式和生态的系统性切换,核心难点在于响应式原理(Object.defineProperty→Proxy)、Composition API 的逻辑组织、生态依赖契约变更及渐进式迁移策略。

Vue 2 升级到 Vue 3 不是版本号替换,而是底层机制、开发范式和工程生态的系统性切换。真正卡住团队的,往往不是语法差异,而是响应式原理变化、API 设计哲学迁移、以及第三方依赖链的连锁反应。
响应式系统重构带来的“隐形断点”
Vue 2 用 Object.defineProperty 逐个劫持属性,导致新增属性、数组索引赋值、深层嵌套初始化等场景必须靠 Vue.set 补救;Vue 3 改用 Proxy,天然支持这些操作——但这也意味着老代码里那些“补丁式写法”会突然失效或产生冗余。
- 直接给
reactive对象添加新字段(如state.user.avatar = url)现在完全响应,无需set - 解构
reactive对象会丢失响应性,必须用toRefs或改用ref+.value - 对大型数据结构,优先考虑
shallowReactive避免过度代理,尤其在表格、树形组件中
Composition API 不是语法糖,而是组织逻辑的新坐标系
很多人把 setup 当作 data + methods 的拼接区,结果写出比 Options API 更混乱的代码。它的本质是按功能切分关注点,让“搜索逻辑”“权限校验”“表单校验”各自内聚。
- 避免在
setup里堆砌所有变量和函数,应拆成useSearch、useForm等组合式函数 -
ref用于基础类型和需要解构的响应式值,reactive更适合对象结构,二者配合使用 - 生命周期钩子必须显式导入(如
onMounted),且不能在条件语句中调用
生态依赖升级不是“换版本”,而是“换契约”
UI 库、状态管理、路由、构建工具……每个核心依赖都从“适配 Vue 2”转向“原生支持 Vue 3”,接口、行为、甚至打包产物格式都变了。
立即学习“前端免费学习笔记(深入)”;
- Element UI → Element Plus:组件名、插槽命名、图标引入方式、暗黑模式配置全部调整
-
Vuex 3 → Pinia:不再需要
mutations,store 可直接导出函数,支持 TypeScript 推导零配置 -
Vue Router 3 → 4:
mode: 'history'被移除,router.beforeEach返回值语义变更,导航守卫需适配 Promise 链 - Webpack → Vite:热更新从秒级降到毫秒级,但需重写别名、代理、环境变量注入等配置
渐进式迁移必须有“隔离层”和“探测器”
全量重写风险高、周期长,真实项目更依赖可控的过渡策略。
- 用
@vue/compat启动兼容模式,在 Vue 3 运行时中模拟 Vue 2 行为,快速验证主流程 - 通过
compilerOptions.compatConfig按模块逐步关闭兼容项(如先关filters,再关asyncData) - 用
vue-migration-helper扫描源码,自动生成含位置、风险等级、修复建议的报告 - 对混入(mixins)、
Vue.extend、事件总线等高危模式,优先封装为组合式函数替代


















