事情是这样子的。。。
组长:把XXX项目 Vue2 升级到 Vue3 吧!(看我最近不忙吧)
我:好的。(就这么愉快的决定了)
GoGoCode
GoGoCode 是一个基于 AST 的 JavaScript/Typescript/HTML 代码转换工具,你可以用它来构建一个代码转换程序来帮你自动化完成如框架升级、代码重构、多平台转换等工作。
全局安装 gogocode-cli
npm install gogocode-cli -g
// 全局安装 gogocode-plugin-prettier,格式化源代码,方便对比代码更改
npm install gogocode-plugin-prettier -g
// 全局安装 gogocode-plugin-vue插件,把 vue2 语法的项目转换成 vue3 的
npm install gogocode-plugin-vue -g
// 全局安装 gogocode-plugin-element插件,把项目代码从 ElementUI 升级到 Element Plus
npm install gogocode-plugin-element -g
格式化源代码
方便对比代码更改。git commit 一次。
gogocode -s ./src -t gogocode-plugin-prettier -o ./src
vue2 语法转换成 vue3
-s 后面是原文件的目录/文件名,-o 后面是输出的目录/文件名,如果两者相同,转换插件会覆盖你的代码。
转换完成,代码已经无法运行,开始解决报错。
依赖升级
gogocode -s package.json -t gogocode-plugin-vue -o package.json
删除 node_modules
npm install
升级依赖Vue2的库
npm install element-plus --save
报错了,可以看到哪些插件是vue2版本的。需要手动升级成vue3版本。
package.json中删除 @fullcalendar相关插件、ant-design-vue(没用不安装了)、element-ui
fullcalendar 插件升级
npm install @fullcalendar/vue3 @fullcalendar/core @fullcalendar/daygrid @fullcalendar/interaction @fullcalendar/timegrid
安装 Element Plus
npm install element-plus --save
gogocode -s ./src -t gogocode-plugin-element -o ./src
解决报错
报错1
原因: App.vue 中引用文件路径错误,其它文件中都是正确的。
解决方法:
改为
报错2
原因: 删除了 (星标或通配符)路由,现在必须使用自定义的 regex 参数来定义所有路由(、/*)
src/router/index.js
改为
报错3
原因: src/lib/directives.js 文件中 window.vueApp = undefined.
解决方法:
src 下新建 initVueApp.js
在 ES6 模块系统中,当一个模块导入其他模块时,这些被导入的模块会首先被执行,所以要新建文件导入,在main 中 window.$vueApp = Vue.createApp(App) 会后执行。
main.js 中引入 initVueApp.js
删除main.js 中 引用
// import * as Vue from 'vue'
// import App from './App.vue'
// window.$vueApp = Vue.createApp(App);
错误4
main.js 中删除 ant-design-vue 相关导入(项目中有Element就够了,项目中好像也没有使用)
报错5
原因: @fullcalendar/vue 已经升级@fullcalendar/vue3,代码还没有改
解决方法:
src/components/common/single/full-calendar.vue 中
import FullCalendar from '@fullcalendar/vue' 改为 import FullCalendar from '@fullcalendar/vue3'
报错6
main.js 中 VueI18n 相关引用删除,没有用到国际化
报错7
原因: ElementUI.Dialog = undefined
解决方法:
使用 window.$vueApp._context.components 代替 ElementUI
打印 window.$vueApp._context.components,原 Dialog 改为了 ElDialog
main.js 中 组件都加了 El
报错8
原因: src/App.vue 中 this.$route = undefined
解决方法:
window.$vueApp.use(store)
window.$vueApp.use(router)
移动到 router.beforeEach((to, from, next) => { } 前边
报错9
原因: @element-plus/icons 要单独安装
解决方法:
错误10
原因: slot下嵌套了一个相同的slot
解决方法:
src/components/common/Sidebar.vue 文件
删除里边的 template,改为:
终于出现页面 header 和菜单了,样式还是错乱的。
main.js 引入 import 'element-plus/dist/index.css'
终端还有88个error
错误11
解决方法:
@click="
page = 1
全局替换成
@click="
page = 1 &&
终端还有69个error
错误12
vue3+element-plus 使用 v-model 报错,有什么其他的改法吗?
VueCompilerError: v-model cannot be used on a prop, because local prop bindings are not writable.
Use a v-bind binding combined with a v-on listener that emits update:x event instead.
解决方法:
v-model= 替换成 :model-value
终端还有39个error
错误13
原因: expects exactly one child element or component,下只能有一个子元素
解决方法: 使用 div 包裹子元素
终端还有37个error
错误14
原因: 同错误11,此类错误统一修改一下。
解决方法:
改为
错误15
Error: Codegen node is missing for element/if/for node. Apply appropriate transforms first.
解决方法:
src/components/page/plan/Index.vue
删除< template v-slot:reference>
错误16
原因: vue-quill-editor已经不支持vue3
解决方法: 更换其它富文本组件
错误17
[vue/compiler-sfc] This experimental syntax requires enabling one of the following parser plugin(s): "jsx", "flow", "typescript".
原因: 使用了jsx语法
解决方法: script 标签上加 lang="jsx"
错误18
原因: 找不到 element-ui/packages/image/src/image-viewer
解决方法:
删除 import ElImageViewer from 'element-ui/packages/image/src/image-viewer' 相关引用
终端 error 0
到这里代码是可以正常运行的了,个别页面有报错,单独解决就可以了。