背景
由于最近有需求需要把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()
遇到大大小小挺多错误的,大多数都是可以批量更改,不少问题也是定位不到位,所以比较耗费时间。也可能有没记全的问题,不管咋说,项目看起来是升级结束了,撒花!!!