从 Vue 2 迁移到 Vue 3,最让人头疼的不是“新功能怎么用”,而是“老代码怎么继续跑”。一个运行多年的项目可能有几百个组件、几十个依赖库,一次性全部改完既不现实也不安全。Vue 官方提供了一个务实的过渡方案:@vue/compat 兼容构建,让 Vue 2 的代码在 Vue 3 环境下最大程度地正常运行,同时逐步提示需要迁移的地方。
@vue/compat 是什么
@vue/compat 是 Vue 3 的一个特殊发行版本,它在 Vue 3 的核心之上模拟了 Vue 2 的大部分已废弃或行为变更的 API。也就是说,你把项目升级到 Vue 3,但安装的是 vue 的兼容构建(@vue/compat 本质上是 vue 包的一个版本,从 3.1 开始提供),它会让那些在 Vue 3 中原本会报错或行为不同的 Vue 2 代码,继续按照 Vue 2 的方式运行——同时在控制台给出废弃警告,告诉你哪行代码需要在未来修改。
简单理解:@vue/compat 就是一个带“兼容模式”的 Vue 3,它同时支持 Vue 2 和 Vue 3 的 API,并充当“翻译官”,让你可以边运行边修警告,最终切换到纯 Vue 3 构建。
为什么要用它,而不是直接改代码
大型项目的迁移有三大难点:
- 代码量大:几百个文件逐一改成组合式 API 不现实,业务迭代不能停。
- 依赖库滞后:你用的某个 Vue 2 生态库(比如
vue2-editor、vue2-datepicker)可能还没发布 Vue 3 版本,或者你暂时没有精力替换。 - 隐性行为变更:一些改动文档里没写清楚,或者只在特定边缘场景触发,直接升级可能导致线上功能静默异常。
@vue/compat 的价值在于:允许项目先跑到 Vue 3 的运行时上,享受 Vue 3 更好的性能和部分新特性(如 Teleport、Fragments),同时用警告信息指导你消除不兼容的旧代码。这种“渐进式迁移”让你可以在日常开发中顺手修复警告,而不是专门停下所有工作搞一次“大爆炸式升级”。
操作步骤:三步从 Vue 2 平滑过渡
第一步:安装 @vue/compat
在你的 Vue 2 项目(假设已经用 Vue CLI 或 Webpack)中,将 vue 升级到 ^3.1.0,同时安装 @vue/compat,并配置构建工具让 vue 指向兼容构建。
npm install vue@^3.1.0 @vue/compat@^3.1.0
然后需要在打包配置(如 vue.config.js 或 vite.config.js)中添加别名,让 vue 解析为 @vue/compat:
// vue.config.js (Vue CLI)
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '@vue/compat')
}
}
如果是 Vite,则在 vite.config.js 中:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
resolve: {
alias: {
vue: '@vue/compat'
}
},
plugins: [vue()]
})
同时,把 vue-template-compiler(Vue 2 编译器)替换为 @vue/compiler-sfc(Vue 3 编译器),因为今后你的 .vue 文件需要按 Vue 3 语法编译。
第二步:修复启动错误
启动项目后,你会发现控制台有一堆警告,也可能会出现一些报错(比如某些 Vue 2 全局 API Vue.prototype 变了)。按照从阻塞到非阻塞的顺序处理:
- 先解决导致白屏或报错的 API 变更:比如
Vue.prototype改为app.config.globalProperties,Vue.component改为app.component,new Vue()改为createApp().mount()。这些改动比较机械,可以写一个适配层或在入口文件中集中处理。 - 处理废弃的组件选项:比如
filters过滤器在 Vue 3 中移除,你需要将模板中的{{ date | format }}改为计算属性或方法调用。 - 处理行为差异:如
v-if与v-for的优先级变了(Vue 3 中v-if更高),$listeners被合并到$attrs等。
第三步:根据控制台警告逐步迁移
@vue/compat 会针对每个废弃的用法给出类似这样的警告:
[Vue compat warn]: DEPRECATED_INSTANCE_LISTENERS (in component <MyComponent>)
每条警告都对应一个兼容开关,可以在构建配置中关闭。当警告消失,说明该项目里已经没有使用这个废弃特性了,你就可以全局关闭这个开关,减小兼容模式的开销,并向“完全 Vue 3 模式”迈进一步。
在 vue.config.js 或 vite.config.js 中可以配置关闭某些兼容项:
// 示例:关闭 $listeners 兼容
resolve: {
alias: {
vue: '@vue/compat'
}
},
// Vite 插件配置
vue({
template: {
compilerOptions: {
compatConfig: {
MODE: 2,
INSTANCE_LISTENERS: false // 关闭该兼容项
}
}
}
})
最终,当所有兼容项警告都消失,且你确认项目已无 Vue 2 特定代码,就可以移除 @vue/compat 别名,安装纯 vue 包,享受 Vue 3 的全部性能和包体优势。
现实中的迁移节奏
实际迁移通常是混合模式的:
- 底层基础设施(路由、状态管理、全局 API)先改,因为影响面大且改动集中。
- 业务组件可以慢慢来,遇到一个改一个,甚至新增组件直接写组合式 API,老组件保持选项式 + compat 模式。
- 第三方库优先寻找 Vue 3 替代品,短期无法替代的可以通过 compat 维持运行,但需评估风险。
整个迁移过程可能持续数周或数月,但 @vue/compat 让你不需要暂停业务需求,而是在日常迭代中“顺手”搞定迁移,最终平滑过渡到 Vue 3。这种务实的迁移策略,是 Vue 官方对开发者最大的体贴。