此篇为 《Vue2+ElementUI 自动转 Vue3+ElementPlus(GoGoCode)》 的扩展!
Vue3 适配
Vue3 不兼容适配
Vue 3 迁移指南 在此,本章只讲述项目或组件库中遇到的问题;
-
Vue3
CSS 深度选择器 有变化,有警告[@vue/compiler-sfc] the >>> and /deep/ combinators have been deprecated. Use :deep() instead.
/* Vue2 写法一 */ .a >>>.b /* Vue2 写法二 */ .a /deep/ .b /* Vue3 写法*/ .a :deep(.b)
-
Vue props 多个类型,不要用 | ,用数组 []。否则报错
expected "indent", got "eos"
expandLevel: { // type: Number | String,// vue2 可以,vue3 报错 type: [Number, String], // vue2/vue3 正确 default: 1, }
GoGoCode 自动升级适配
-
v-model:value
报错,全局搜v-model:value
并全局替换为v-model
。其实Vue2
和Vue3
都不加:value
,不知为何转换时加上了… -
插槽报错
Duplicate slot names found
发现重复的插槽名称 。仅两个 slot 在一块报错… -
HTML
元素上的方法,例如@click=
中有多个表达式仅换行没分号 ; ,这是语法错误。建议多个表达式就写在方法里
Webpack 转 Vite 适配
动态加载文件 Webpack
用 require.context
, Vite
用 import.meta.glob
- src\params.js
- src\store\index.js
- src\components\onemap\func.js 注意这里是异步加载,否则初始化最先加载,找不到 app 对象
Webpack
用 require.context
const modulesList = require.context("./src/components", true, /\.vue$/);
const modules = modulesList.keys().reduce((obj, modulePath) => {
// 文件名
const moduleName = modulePath.replace(/^\.\/(.*)\/(.*)\.\w+$/, "$2");
// 模块对象
let moduleObj = modulesList(modulePath);
// 放入模块
obj[moduleName] = moduleObj.default;
return obj;
}, {});
Vite
用 import.meta.glob
// 注意加在 `eager: true` 是同步处理
const modulesList = import.meta.glob('./src/components/**/*.vue', { eager: true });
const modules = Object.keys(modulesList).reduce((obj, path) => {
// 文件名
const moduleName = path.replace(/(.*\/)*([^.]+).*/ig, "$2");
// 放入模块
obj[moduleName] = modulesList[path].default;
return obj;
}, {})
const modulesFiles = import.meta.glob('./funcs/**/*.vue')
let modules = {};
for (const path in modulesFiles) {
modulesFiles[path]().then((mod) => {
// 文件名
const moduleName = path.replace(/(.*\/)*([^.]+).*/ig, "$2");
// 放入模块
modules[moduleName] = mod.default;
})
}
Element Plus 适配
- el-button 警告
[props] [API] type.text is about to be deprecated in version 3.0.0, please use link instead.
解决: 官网中 el-button
type=“text” 用于链接按钮已在 v3.0.0 废除
// 原
<el-button type="text">文字按钮</el-button>
// 改为
<el-button type="primary" link>文字按钮</el-button>
- el-input 警告
Invalid prop: validation failed. Expected one of ["", "default", "small", "large"], got value "mini".
解决: 属性 size
在 ElementUI
和 ElementPlus
之间有差异
- Element UI 用
medium / small / mini
- Element Plus 用
large / default / small
- el-tabs 方法 tab-click 返回值 ElementUI 和 ElementPlus 不一样
差异: ElementUI el-tabs 和 ElementPlus el-tabs
- el-input ElementUI 和 ElementPlus 有点差异,ElementPlus 多嵌套了一层
el-input__wrapper
解决: 改造 src\assets\scss\elements\input.scss
,设置 padding:0 !important
- Element Icon 图标 警告
voided by marking the component with
markRawor using
shallowRefinstead of
ref.
解决: 以转换后一张图系统文件 src\components\onemap\mode-refreshing\head.vue
为例。代码第 10
行 ElIconSetting
,放在 data()
中,做了深度响度,会有必要的开销。
// 修改前
import {
Setting as ElIconSetting,
DataAnalysis as ElIconDataAnalysis,
SwitchButton as ElIconSwitchButton,
} from '@element-plus/icons-vue'
export default {
data() {
return {
ElIconSetting,
ElIconDataAnalysis,
ElIconSwitchButton
}
},
}
提示加上 markRaw 不被代理 或 shallowRef 浅层响应。如代码 2,11-13
行
// 修改后
import { shallowRef } from 'vue'
import {
Setting as ElIconSetting,
DataAnalysis as ElIconDataAnalysis,
SwitchButton as ElIconSwitchButton,
} from '@element-plus/icons-vue'
export default {
data() {
return {
ElIconSetting: shallowRef(ElIconSetting),
ElIconDataAnalysis: shallowRef(ElIconDataAnalysis),
ElIconSwitchButton: shallowRef(ElIconSwitchButton),
}
},
}