简单记录一次项目从Vue2升级Vue3的过程
1.重新初始化一个新的vue2项目,无需安装其他包
vue create [new-project]
- 查看新项目中vue2的版本,最好与原始项目一致或相差不大
- 根据需要安装css预处理器如less-loader
2.卸载vue2模板编译依赖
npm uninstall vue-template-compiler
3.查看新项目vue2版本,安装vue3兼容依赖
npm install @vue/compat@[version]
npm install @vue/compiler-sfc@[version]
4.尝试启动项目编写vue3组件进行验证
<script setup>
import { ref } from "vue";
const name = ref("owooov");
</script>
<template>
<h1>Hello {{ name }}</h1>
</template>
- 正常运行进入下一步
5.根据项目情况补充安装依赖或升级依赖,并根据升级的版本进行初始化
以下是一些依赖升级及配置过程
5.1 升级vue-router
- 安装
npm npm install vue-router
- 初始化
const routes = []
// vue-router3
import VueRouter from 'vue-router'
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
// vue-router4
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes
})
5.2 升级Vuex
- 安装
npm install vuex
- 初始化
//vuex3
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({...})
//vuex4
import { createStore } from 'vuex'
export const store = createStore({...})
5.3 升级ElementUI到ElementPlus
- 安装
npm install element-plus
- 初始化
//element-ui
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
//element-plus
import ElementPlus from "element-plus";
import "element-plus/theme-chalk/index.css";
import zhCn from "element-plus/es/locale/lang/zh-cn";
-
使用gogocode工具升级 element-ui 到 element-plus
- 高级配置请参考下面链接
- github.com/thx/gogocod…
-
基本使用(转换时做好备份)
- src-old为原始项目的src根目录,src为新项目src根目录
npm install -g gogocode-cli
gogocode -s ./src-old -t gogocode-plugin-vue -o ./src
- 转换成功后将src下的组件目录复制到新项目的对应位置
6 兼容性错误处理
6.1 vue初始化,指令注册、组件注册方式不同需要处理
// vue2
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI, {
size: 'mini'
})
Vue.component('data-card', DataCard)
Vue.directive('dragable', {...})
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
// vue3
import { createApp, configureCompat } from 'vue'
import App from './App.vue'
import router from './router'
import { store } from './store'
import ElementPlus from 'element-plus'
import 'element-plus/theme-chalk/index.css'
const app = createApp(App)
app.use(ElementPlus)
// 组件
app.component('data-card', DataCard)
// 指令
app.directive('dragable', {...})
app.use(router)
app.use(store)
app.mount('#app')
- 重新启动项目,解决错误
6.2 css穿透语法可能出现警告
sass ::v-deep <inner-selector>less /deep/ <inner-selector>深度指令统一使用 :deep (<inner-selector>)
6.3 Can't resolve '@element-plus/icons' in 'D:\code\components'
// vue.config.js
config.resolve.alias.set('@element-plus/icons','@element-plus/icons-vue')
6.4 清除在Vue3中过期的配置
config.productionTip
6.5 ElementUI和ElementPlus的图标名称可能有对应问题
//vue2
// <i class="el-icon-s-fold" title="折叠"></i>
// <i class="el-icon-s-unfold"></i>
//vue3
//<el-icon><Expand /></el-icon>
//<el-icon><Fold /></el-icon>
6.6 使用gogocode工具升级ElementUI后,图标不能触发点击事件
- element-ui中是基于字体的,使用el-icon是基于svg进行渲染的,svg默认不监听click事件 需要使用元素进行包裹
<i @click="handleClose"></i><el-icon class="close-btn" @click="handleClose"><el-icon-close /></el-icon>
6.7 keepalive组件使用方式不同
vue2
<keep-alive>
<router-view />
</keep-alive>
vue3
<router-view v-solt="{component}">
<keep-alive>
<component :is="component"/>
</keep-alive>
</router-view>
6.8 vue-router4路由校验更加严格,路由名称不能重复
main.js:37 [Vue Router warn]: No match found for location with path "/mgt/index"
6.9 Echarts在升级在resize触发错位
-
dataSample.js:115 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'type') at Object.reset (dataSample.js:115:1) //if (count > 10 && coordSys.type === 'cartesian2d' && sampling) { -
vue3 会将Echarts实例变成响应式对象, 出现问题 错误原因:因为vue3.0使用的是proxy的模式监听响应式,this.chart会被在vue内部转换成响应式对象,从而在resize的时候获取不到coordSys.type
-
解决这时候就体现封装echarts组件的好处,只改一处即可
import { markRaw } from ‘vue’
this.chart = markRaw(echarts.init(document.getElementById(this.id)))
6.10 警告信息
(deprecation COMPILER_NATIVE_TEMPLATE) <template> with no special directives will render as a native template element instead of its inner content in Vue 3.COMPILER_NATIVE_TEMPLATE警告,这通常意味着你正在使用<template>标签而没有指定任何特殊的指令,这在 Vue3 的<script setup>语法中是不被推荐的做法。
6.11 ElementUI到ElementPlus的其他兼容问题
el-dialog visiable属性改为 :model-value 或 v-modelel-tree 插槽变化 solt-scope 变为 default
6.12 其他UI界面问题自行处理
- 如重置样式不生效等自行处理