此篇文章用于记录 Ant Design Pro 项目在开发过程中遇到的一些问题。
umi 版本:
^4
antd 版本:5
antd pro 版本:^2
react 版本:18
一、设置紧凑布局
1.1 构建时配置
1.1.1 compact
// config/config.ts
export default defineConfig({
antd: {
compact: true
}
})
antd 里有个 compact 属性,能够直接开启紧凑主题,但是在开启后在项目构建过程中会报错(如下图),但是具体原因还未找到,社区里有很多人也在问这个问题,但是官方貌似还没有给出回应(如果有,请敲🔨我一下~):
所以可以尝试使用方法2👇。
1.1.2 configProvider
配置 antd 的 configProvider:
// config/config.ts
import { theme } from 'antd';
export default defineConfig({
configProvider: {
theme: {
algorithm: theme.compactAlgorithm,
}
}
})
但是发现单单在构建过程中配置还是不生效,那我们就在运行中也配置上。
1.2 运行时配置
// src/app.tsx
import { theme } from 'antd';
import type { RuntimeAntdConfig } from '@umijs/max';
export const antd: RuntimeAntdConfig = (memo) => {
memo.theme ||= {};
memo.theme.algorithm = theme.compactAlgorithm;
return memo;
};
注意:运行和构建都要添加配置,仅配置一个是不生效的。
具体配置请查看umi官方文档,在这里~
二、上传图片到阿里云 OSS
三、表单规则校验
3.1 手机号校验
<ProFormText
rules={[
{
message: '请输入手机号',
required: true
},
{
pattern: /^1[3|4|5|7|8][0-9]\d{8}$/,
message: '手机号格式错误'
}
]}
name="mobile"
label="手机号"
placeholder="请输入手机号"
/>
3.2 名称限制只能使用中英文和数字
<ProFormText
rules={[
{
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9]+$/,
message: '只能输入中英文和数字'
}
]}
name="name"
label="姓名"
placeholder="请输入姓名"
/>
3.3 验证两次输入的密码是否一致
<ProFormText.Password
name="password"
label="密码"
placeholder="请输入密码"
fieldProps={{
visibilityToggle: false // 是否显示切换按钮或者控制密码显隐
}}
/>
<ProFormText.Password
rules={[
({getFieldValue}) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次输入的密码不一致'));
},
})
]}
name="rePassword"
label="确认密码"
placeholder="请输入确认密码"
fieldProps={{
visibilityToggle: false
}}
/>
3.4 校验身份证号
<ProFormText
rules={[
{
message: '请输入身份证号',
required: true,
},
{
pattern: new RegExp(/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,'g'),
message: '请输入正确的身份证号',
},
]}
name="idNumber"
label="身份证号"
placeholder="请输入身份证号"
/>
四、根据权限进行菜单的展示和路由重定向
// routes.ts
export default [
{
name: '运营管理',
path: '/operateManage',
// 控制菜单是否展示
access: 'canService',
routes: [
{
path: '/operateManage',
wrappers: [
'@/wrappers/auth',
],
}
]
}
]
// src/wrappers/auth.ts
import { history, useModel } from '@umijs/max';
export default () => {
const { initialState } = useModel('@@initialState');
const { currentUser } = initialState || {};
const isService = currentUser?.access === 'service';
const path = isService ? '/operateManage/account/master' : '/operateManage/account/user';
return history.push(path);
}
// src/access.ts
export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) {
const { currentUser } = initialState ?? {};
return {
canService: currentUser && (currentUser.access === 'admin' || currentUser.access === 'service'),
canAdmin: currentUser && currentUser.access === 'admin'
};
}
五、表单赋值问题
5.1 第一次打开弹窗时,表单使用 formRef.current.setFieldsValue(values) 赋值不成功
原因: 在 Modal 打开(visible 设置为 true)的时候,form 表单还未渲染,所以 formRef.current 为 undefined。
解决方法:
- 方案1:加个
setTimeout才能拿到FormRef
const handleOpenEdit = (record: BMECAPI.AreaListItem) => {
setIsOpen(true);
setTimeout(() => {
formRef.current?.setFieldsValue(record);
});
};
- 方案2:Form 有个
onInit属性(但是这个属性在官文中并未标识),可以用来初始化表单数据(👍 最优解)
const formRef = useRef<ProFormInstance>();
<ProForm
onInit={() => formRef.current?.setFieldsValue(record)}
formRef={formRef}
>
</ProForm>
持续更新中⌛️~