记录一次项目从Vue2升级Vue3的过程

929 阅读4分钟

简单记录一次项目从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

  • 基本使用(转换时做好备份)

    • 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-model
  • el-tree 插槽变化 solt-scope 变为 default

6.12 其他UI界面问题自行处理

  • 如重置样式不生效等自行处理

7 更多问题请参考Vue2项目升级升级官方文档