Vue 2 项目如何迁移到 Vue 3?
先升级到 Vue 2.7,用组合式 API 和 <script setup> 改写并清理 filters、$listeners、.sync 等写法;检查组件库、路由和 IE11 等依赖边界;再用 @vue/compat 迁移构建逐项消除警告,同时升级 vue-router 4、Vuex 4 或改用 Pinia。
参考答案
Vue 2 已于 2023-12-31 停止维护,本题 Vue 2 部分以 2.7 为准。通信写法的具体改动见《Vue 2 有哪些组件通信方式?哪些写法在 Vue 3 中被移除或改变?》。
简答
- 先评估能否迁移:依赖 Vue 2 内部 API 的库、尚无 Vue 3 版本的组件库、必须支持 IE11 的项目,都可能需要暂留 Vue 2。
- 可以先升级到 Vue 2.7:它内置组合式 API、
<script setup>和 SFC CSSv-bind,能在 Vue 2 上提前改写代码,缩小之后的差异。 - 正式迁移可用
@vue/compat:它是可配置 Vue 2 兼容行为的 Vue 3 构建,默认以 Vue 2 模式运行,对废弃用法发出警告,可以逐项修复。 - 主要破坏性变更包括
createApp取代new Vue()、组件v-model重做并移除.sync、$listeners/$on/filters 移除、beforeDestroy/destroyed改名、过渡类名变化等。 - 生态同步升级:vue-router 4、Vuex 4(或改用官方推荐的 Pinia)、
vue-template-compiler换成@vue/compiler-sfc。
第一步:评估依赖与环境
迁移构建文档列出了几类限制:
- 依赖 Vue 2 内部 API 或未公开行为的库,最常见的是访问 VNode 私有属性。
- 依赖 Vuetify、Quasar、ElementUI 等组件库时,最好等它们的 Vue 3 兼容版本。
- Vue 3 不支持 IE11,需要支持 IE11 的项目只能留在 Vue 2。
- 自定义 SSR 迁移成本更高,
vue-server-renderer要换成@vue/server-renderer。
第二步:在 Vue 2.7 上提前改写
2.7 发布说明列出的移植功能有组合式 API、SFC <script setup>、SFC CSS v-bind,以及 defineComponent() 的类型推断改进。原先使用 @vue/composition-api 插件的项目,把导入改成从 vue 导入即可。
同时要知道 2.7 的边界:组合式 API 基于 Vue 2 的 getter/setter 响应式实现;createApp()、<script setup> 中的顶层 await、模板表达式中的 TypeScript 语法和 Reactivity Transform 没有移植。
这一阶段还可以先清理迁移后不再支持的写法:废弃的具名/作用域插槽语法(2.6 已支持新语法)、filters、$listeners、.sync、EventBus 等。
第三步:用 @vue/compat 切换到 Vue 3
迁移构建文档给出的流程:
- 升级工具链:自定义 webpack 升级
vue-loader到 16;Vue CLI 用vue upgrade,或改用 Vite。 - 在
package.json中把vue升到 3,安装同版本的@vue/compat,用@vue/compiler-sfc替换vue-template-compiler。 - 构建配置中把
vue别名指向@vue/compat,并在编译选项中设置compatConfig: { MODE: 2 }。
JavaScript
// vite.config.js
export default {
resolve: { alias: { vue: '@vue/compat' } },
plugins: [
vue({ template: { compilerOptions: { compatConfig: { MODE: 2 } } } }),
],
};
- 先修复编译期错误(如 filters),再逐个处理浏览器控制台中的运行时警告。每个警告有 ID,例如
GLOBAL_MOUNT(new Vue()→createApp)、OPTIONS_BEFORE_DESTROY。 - 过渡类名变化是唯一没有运行时警告的特性,需要全局搜索
.*-enter、.*-leave类名。 - 改用
createApp挂载,升级 Vuex 4 和 vue-router 4。 - 冲突较大的组件可以通过
compatConfig选项按组件切换到 Vue 3 行为;警告全部清除后移除迁移构建。
状态管理:Vuex → Pinia
Vue 官方文档说明 Pinia 已承担 Vuex 的角色,Vuex 进入维护模式,新项目推荐 Pinia。迁移时可以先升级 Vuex 4 保证运行,再按模块逐步改写为 Pinia store。
常见追问
- 为什么不直接重写?大型项目一次性重写风险高;2.7 + 迁移构建允许应用在每一步都保持可运行。
- 迁移构建能长期使用吗?不能。它的目的是过渡,部分特性在 Vue 2 和 Vue 3 中行为冲突,最终需要移除并切换到正式的 Vue 3。
- 必须先用组合式 API 吗?不必。Vue 3 仍完整支持选项式 API,组合式 API 是可选的改写方向。