vue2+element ui升级vue3+element plus+vite+ts踩坑记录

背景

由于最近有需求需要把vue3项目的功能搬到vue2项目中,而vue3中大多数用的组件库组件,组件库又是用elment plus+vue3写的。为了防止后续搬运改写麻烦,所以决定升级旧项目。

直接用vite脚手架生成了一个新的vue3项目,引入element plus组件,并且把除了git文件夹以外得旧项目文件直接复制到新项目,然后解决不兼容问题。

以下是在升级中遇到的一些问题总结

一、插件

jsx需要引入@vitejs/plugin-vue-jsx

之前得项目用了vue2中得render方法,直接return了对应得模板,升级到vue3后,需要引入@vitejs/plugin-vue-jsx插件,并在vite中配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  plugins: [
    vue(),
    vueJsx()]
    })

因为vue2项目都没有指定jsx类型,所以需要在使用了jsx的组件中得js指定对应得lang=jsx

二、 element-plus

使用自动引入插件后自定义主题色不生效

官网上有提供自定义主题色功能,但是跟着配置后不生效,查了一下,跟vite中的配置有关,使用自动导入插件时,记得配置

ElementPlusResolver({
          importStyle: 'sass',
        })

详情配置如下

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import path from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin } from 'vite-plugin-style-import'
import VueSetuoExtend from 'vite-plugin-vue-setup-extend'

export default defineConfig({
plugins:[
vue(), vueJsx(),VueSetuoExtend(),
AutoImport({
      // Auto import functions from Vue, e.g. ref, reactive, toRef...
      // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
      imports: ['vue','vue-router','@vueuse/core'],
      // Auto import functions from Element Plus, e.g. ElMessage, ElMessageBox... (with style)
      // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
      resolvers: [
        SpectrumResolver(),
        ElementPlusResolver({
          importStyle: 'sass'
        }),
      ],
      dirs: ['src/api/**', 'src/hooks/*'],
      dts: true,
    }),

    Components({
      dirs: ['src/components'],
      resolvers: [
        // Auto register Element Plus components
        // 自动导入 Element Plus 组件
        ElementPlusResolver({
          importStyle: 'sass',
        })
      ],
      include: [
        /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
        /\.vue$/, /\.vue\?vue/, // .vue
      ],
      dts: true,
    }),
    // unplugin-vue-components不支持jsx,使用jsx时仍然需要import组件,用于import组件时自动引入样式
    createStyleImportPlugin({
      libs: [
        {
          libraryName: 'element-plus',
          ensureStyleFile: true,
          esModule: true,
          resolveStyle: (name) => `element-plus/es/components/${name.slice(3)}/style/index.mjs`,
        },
      ],
    }),
],
css: {
    preprocessorOptions: {
      scss: {
        additionalData: ` @use "@/styles/element/index.scss" as *;`,
        api: 'modern-compiler' // 如果您的终端提示 legacy JS API Deprecation Warning, 您可以配置以下代码在 vite.config.ts 中
      },
    },
  },
})

其中css的additionData配置的路径,就是跟着你要设置的主题色

src/styles/elment/index.scss

@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'primary': (
      'base': #0E42B9,
    ),
  ),
);

编译时$ref找不到

从element ui升级到element plus时,有出现

$colors: () !default;
$colors: map.deep-merge(
  (
    'white': #ffffff,
报$ref找不到的错误,sass未能兼容

解决方案,将element plus升到最新版本(最近更新了新版本,似乎解决了问题)

keep-alive

升级vue3后,对应的router-vue也要升级到第四版本,其中router-view对keep-alive的写法变了,正确写法如下

<router-view v-slot="{ Component }">
   <transition name="fade-transform" mode="out-in">
      <keep-alive :exclude="noAlivePage" :include="keepAliveList">
          <component :is="Component" :key="key" />
      </keep-alive>
   </transition>
</router-view>

其中include内的才会有对应的缓存,而想要缓存上组件,必须每个组件都命名,并存入对应的keepAliveList。因为是vue2升上到vue3,使用插件vite-plugin-vue-setup-extend,并在每个页面的setup中给name赋值即可

<script setup lang="tsx" name="componentName">

自动导入

用了自动导入插件,发现自定义的文件夹方法,在导入文件内找不到,即没有自动导入
解决方案,升级unplugin-auto-import,unplugin-vue-components

element ui 与element plus 的组件差异

以下简称element ui为ui,element plus为plus

el-select

因为element plus改了flex布局,适应父组件100%,如果没有设置el-select,宽度会很小。

el-dialog

ui中控制dialog打开时visible,plus是以v-model控制

el-date-picker

plus中只能以v-model赋值和监听

el-message

如果vue2项目中在js中有用到this.$message,则需要全局定义一个message变量,绑定ElMessage

el-loading

plus中需要主动导入loading后,组件上使用v-loading才生效

el-radio

plus中radio的值不再是label获取,变成了value获取

三、vue2与vue3写法

vue3与vue2大多数是可以兼容的,但是有部分写法不同

props

vue3中不允许更改props传入的值,需得更改以前的错误写法,否则不能正确赋值

$set

vue3中废弃了$set

sync同步

vue3中使用v-model,sync不生效

filter

vue3中废弃了filter

环境变量获取

此次升级了用的vite,所以获取对应的环境变量不再是process.env,变为import.meta.env

大体上是这些问题,小的问题可能还有以前数据处理没有规划好,比如数据很大的接口没有分页导致页面卡顿,需要优化。样式上::v-deep废弃了,需要改为:deep()

遇到大大小小挺多错误的,大多数都是可以批量更改,不少问题也是定位不到位,所以比较耗费时间。也可能有没记全的问题,不管咋说,项目看起来是升级结束了,撒花!!!

### Vue2Vue3写法区别 #### 虚拟DOM的改进 Vue 3 对虚拟 DOM 进行了重写,提升了渲染效率和内存占用情况。这种底层架构上的改变使得应用运行更加流畅高效[^1]。 #### 插槽(Slot)语法更新 在 Vue 2 中可以使用 `slot="xxx"` 来定义具名插槽,在 Vue 3 则不再支持这种方式,取而代之的是更统一且功能更强的 `v-slot` 指令来指定作用域插槽的位置以及传递数据给子组件。例如: ```html <!-- Vue2 --> <uni-nav-bar> <view slot="left" class="city"> <!-- ... --> </view> </uni-nav-bar> <!-- Vue3 --> <uni-nav-bar> <template v-slot:left> <view class="city"> <!-- ... --> </view> </template> </uni-nav-bar> ``` #### 组件属性(props) Vue 3 修改了一些有关 props 定义的方式,现在允许开发者通过 TypeScript 类型声明来进行静态类型检查和支持更好的编辑器提示服务[^4]。 ```javascript // Vue2 props: { message: String, } // Vue3 (TypeScript) interface Props { message?: string; } defineProps<Props>(); ``` --- ### 迁移指南要点 当考虑从 Vue 2 升级Vue 3 时,由于二者存在一定的兼容性和特性差异,建议采取渐进式的迁移策略,并充分测试现有业务逻辑以确保平稳过渡[^2]。 - **逐步替换旧版依赖**:先将项目中的第三方库版本同步至最新稳定版; - **调整模板结构**:按照上述提到的新规修改 HTML 结构; - **重构代码片段**:针对 API 变化部分重新编写相应模块; - **利用官方工具辅助**:借助社区提供的自动化脚本简化重复劳动;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值