antd升级到4.x
JeecgBoot
3.6.2+
版本已完成升级,老版本用户可以参考。
antd官方升级文档 jeecg-vue3 从ant-design-vue3.x升级4.x需要做的工作及注意事项:
一、针对4.x API变动对项目代码进行更改:
- 组件弹框的class统一由 dropdownClassName 改成 popupClassName
涉及的组件:
- AutoComplete
- Cascader
- Select
- TreeSelect
- TimePicker
- DatePicker
- Mentions
<template>
<a-select
-- dropdownClassName="my-popup"
++ popupClassName="my-popup"
/>
</template>
- 组件弹窗受控可见统一由 visible 改成 open。(封装组件 BasicDrawer 和 BasicModal 组件做了兼容可不调整)
涉及的组件:
- Drawer
- Modal
- Dropdown
- Tooltip
- Popover (绝大多属性同Tooltip)
- Popconfirm
<template>
<a-modal
-- :visible="visible"
++ :open="visible"
>
content
</a-modal>
</template>
- 组件弹窗事件由 visibleChange 改成 openChange 。
涉及的组件:
- Drawer
- Modal
- Tooltip
- Dropdown
- Popover (绝大多属性同Tooltip)
- Popconfirm
<template>
<a-modal
-- :visibleChange="handleVisibleChange"
++ @openChange="handleVisibleChange"
>
content
</a-modal>
</template>
- 封装组件 BasicDrawer 和 BasicModal 组件做了兼容,既支持原先的 visible 和 visibleChange 也支持 open 和 openChange,升级之后可不调整。
- Tag 组件 visible 已移除。
<template>
<a-tag
-- :visible="visible"
++ :if="visible"
>
tag
</a-tag>
</template>
- Slider 组件 tooltip 相关 API 收敛到 tooltip 属性中。
<a-slider
-- :tooltipVisible="visible"
++ :tooltip="{ open: visible }"
/>
二、系统主题:
因antd4.x放弃了less,但是jeecg-vue3中还要大量less变量,所以要兼容两者。
main.ts
import 'uno.css';
import '/@/design/index.less';
+ import 'ant-design-vue/dist/reset.css';
build/vite/plugin/theme.ts 文件
build/generate/generateModifyVars.ts 文件
import { primaryColor } from '../config/themeConfig';
// import { getThemeVariables } from 'ant-design-vue/dist/theme';
import { resolve } from 'path';
import { generate } from '@ant-design/colors';
import { theme } from 'ant-design-vue/lib';
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
const { defaultAlgorithm, defaultSeed } = theme;
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
return generate(color, {
theme,
});
}
/**
* less global variable
*/
export function generateModifyVars() {
const palettes = generateAntColors(primaryColor);
const primary = palettes[5];
const primaryColorObj: Record<string, string> = {};
for (let index = 0; index < 10; index++) {
primaryColorObj[`primary-${index + 1}`] = palettes[index];
}
const mapToken = defaultAlgorithm(defaultSeed);
const v3Token = convertLegacyToken(mapToken);
console.log(v3Token)
return {
...v3Token,
// ...modifyVars,
// Used for global import to avoid the need to import each style file separately
// reference: Avoid repeated references
hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
'primary-color': primary,
...primaryColorObj,
'info-color': primary,
'processing-color': primary,
'success-color': '#55D187', // Success color
'error-color': '#ED6F6F', // False color
'warning-color': '#EFBD47', // Warning color
//'border-color-base': '#EEEEEE',
'font-size-base': '14px', // Main font size
'border-radius-base': '2px', // Component/float fillet
'link-color': primary, // Link color
'app-content-background': '#fafafa', // Link color
};
}
src/App.vue 文件
<template>
<ConfigProvider :theme="appTheme" :locale="getAntdLocale">
<AppProvider>
<RouterView />
</AppProvider>
</ConfigProvider>
</template>
<script lang="ts" setup>
import { watch, ref } from 'vue';
import { theme } from 'ant-design-vue';
import { ConfigProvider } from 'ant-design-vue';
import { AppProvider } from '/@/components/Application';
import { useTitle } from '/@/hooks/web/useTitle';
import { useLocale } from '/@/locales/useLocale';
import { useAppStore } from '/@/store/modules/app';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { ThemeEnum } from '/@/enums/appEnum';
import { changeTheme } from '/@/logics/theme/index';
const appStore = useAppStore();
// 解决日期时间国际化问题
import 'dayjs/locale/zh-cn';
// support Multi-language
const { getAntdLocale } = useLocale();
useTitle();
// update-begin--author:liaozhiyang---date:20231215---for:【QQYUN-6366】升级到antd4.x
const appTheme: any = ref({});
const { getDarkMode } = useRootSetting();
watch(
() => getDarkMode.value,
(newValue) => {
delete appTheme.value.algorithm;
if (newValue === ThemeEnum.DARK) {
appTheme.value.algorithm = theme.darkAlgorithm;
}
appTheme.value = {
...appTheme.value,
};
},
{ immediate: true }
);
watch(
appStore.getProjectConfig,
(newValue) => {
const primary = newValue.themeColor;
appTheme.value = {
...appTheme.value,
...{
token: {
colorPrimary: primary,
wireframe: true,
fontSize: 14,
colorSuccess: '#55D187',
colorInfo: primary,
borderRadius: 2,
sizeStep: 4,
sizeUnit: 4,
colorWarning: '#EFBD47',
colorError: '#ED6F6F',
},
},
};
},
{ immediate: true }
);
setTimeout(() => {
appStore.getProjectConfig?.themeColor && changeTheme(appStore.getProjectConfig.themeColor);
}, 300);
// update-end--author:liaozhiyang---date:20231215---for:【QQYUN-6366】升级到antd4.x
</script>
<style lang="less">
// update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
img {
display: inline-block;
}
// update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
</style>
三、需要注意事项:
- columns.customRender返回 cell props 被废弃,须使用columns.customCell替代。
- 某些组件 css选择器权重 有变动。(所有选择器都必须在组件根类名之后)
3.x .ant-layout-header{height: 64px;}
4.x .ant-layout .ant-layout-header{height: 64px;}
3.x .ant-drawer-header{position: relative;display: flex;}
4.x .ant-drawer .ant-drawer-header{position: relative;display: flex;}
- 某些组件样式有被舍掉。
3.x 组件自带样式
.ant-modal-close-x{
display: block;
width: 56px;
height: 56px;
font-size: 16px;
font-style: normal;
line-height: 56px;
text-align: center;
text-transform: none;
text-rendering: auto;
}
4.x 组件自带样式
.ant-modal .ant-modal-close-x {
display: block;
font-size: 16px;
font-style: normal;
line-height: 22px;
text-align: center;
text-transform: none;
text-rendering: auto;
}
- table中 #headerCell 作用域插槽 column.title 可能会得到对象。
当table有展开行时:
3.x 第一列#headerCell中column.title是""
4.x 第一列#headerCell中column.title是对象
- 打包生产访问有报错,如果报错信息是在手工分包中可以试着在vite.config.js去掉这个手工分包。
- Drawer组件的 class、 style 作用于 .ant-drawer-content 元素上,原先作用于根元素(.ant-drawer)。如果需要作用于根元素需要改成rootClassName、rootStyle.
- Drawer组件的 zIndex 作用于Drawer( .ant-drawer-content-wrapper),3.x是作用最外层容器。如想作用于最外层容器可写在rootStyle里面。
- drawer组件打开状态3.x在挂载元素上会自动添加 overflow:hidden 属性和ant-scrollling-effect类名。4.x这俩都没了,目前检查看是没影响。overflow:hidden可能特殊情况下有影响需要手动添加。
- getPopupContainer 在4.x版本特殊应用场景(其他大多数没问题,根本原因待查)下回调函数的 node 会有 undefined 的情况,这时候可使用可选链写法兼容下(会执行多次)。在3.x版本没问题(只执行一次)。
<template>
<TimePicker
:value="innerTimeValue"
allowClear
:format="format"
popupClassName="j-vxe-time-picker"
style="min-width: 0"
v-model:open="openPicker"
v-bind="cellProps"
@change="handleChange"
:getPopupContainer="(node) => {console.log('- node -:',node);return node?.parentNode;}"
/>
</template>
升级小技巧
:visible="visible"
:open="visible"
1、替换旧参数名
匹配搜索:visible=替换为:open=
匹配搜索visibleChange=替换为openChange=
清单参考https://next.antdv.com/docs/vue/migration-v4-cn
2、搜索dropdownClassName=替换成popupClassName
3、搜索BasicModal.*:height=,修改height为maxHeight