相信很多同学都用过 Ant Design 这一 react 著名组件库,而 ProComponents 则是在 antd 之上进行封装的页面级组件库(指一个组件就可以搞定一个页面)。它同时也是 Ant Design Pro 中后台框架所用的主要组件库。如果你手上有要用 react 开发的中后台新项目又人手不够的话,我强烈推荐你体验一下这个库。可以极大的减少日常 CRUD 的代码量并统一风格。
在 ProComponent 中,最为核心的就是 ProForm(表单)和 ProTable(表格)两个组件,面对数量繁多的配置项,很多人都会在文档中迷失自我,本文就来总结了一些常见的配置。
ProTable
ProTable 最大的好处就是它集成了表格的查询条件和分页配置。只需要配置表格列就可以自动生成对应的查询 form。除此之外它提供的插槽和细节小功能用起来也十分舒服。
1、基础流程
先来简单介绍一下基本的使用,主要就是两部分:表格列配置、查询请求,最后把他俩塞给 ProTable 就完事了:
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { ProTable, ModalForm } from '@ant-design/pro-components';
import React, { useRef, useState } from 'react';
type GithubIssueItem = {};
export default () => {
const actionRef = useRef<ActionType>();
const columns: ProColumns<GithubIssueItem>[] = [
{
title: '审批单号',
key: 'showTime',
dataIndex: 'showTime',
valueType: 'text',
},
{
title: '任务状态',
key: 'showTime3',
dataIndex: 'showTime3',
valueType: 'select',
valueEnum: {
open: {
text: '审核中',
status: 'Error',
},
closed: {
text: '已完成',
status: 'Success',
},
processing: {
text: '已作废',
status: 'Processing',
},
submited: {
text: '待提交',
status: 'Processing',
},
},
},
{
title: '时间',
key: 'showTime5',
dataIndex: 'showTime5',
valueType: 'date',
},
{
title: '资料大类',
key: 'showTime9',
dataIndex: 'showTime9',
valueType: 'select',
fieldProps: { mode: 'multiple' },//多选
valueEnum: {
pages: {
text: '页面',
status: 'pages',
},
Copywriting: {
text: '文案',
status: 'Copywriting',
},
},
},
{
title: '操作',
valueType: 'option',
key: 'option',
render: (text, record, _, action) => [<a>详情</a>],
},
];
//获取table数据
const getTableData = async (param: any) => {
const params = {
...param,
};
// const { data, success } = await fetchCompanyList(params);
return {
data: [{}],
success: true,
page: 1,
total: 0,
};
};
return (
<>
<ProTable<GithubIssueItem>
columns={columns}
actionRef={actionRef}
request={getTableData}
headerTitle="结果查询"
search={{ labelWidth: 'auto' }}
/>
</>
);
};
然后你就得到了这个简单但五脏俱全的表格:
在 ProTable 中查询条件和表格列是一一对应的,通过columns来配置,也就是说每个列都会生成一个对应的查询条件,注意列配置中的 valueType 字段,不同的值可以让输入框变成日期、下拉、多选、进度条等等详细点击这里查看,然后 ProTable 就会按照对应的格式渲染表格字段和查询表单项。
在发起查询时,你所有的查询条件和分页参数都会被传递给 request 参数对应的函数上,最后把查询到的结果按照给定的格式返回出去即可,注意这个函数可以是异步函数,ProTable 会根据这个函数的状态自动渲染相关的加载动画,非常舒服。
同时所有 antd Table Column 支持的配置项都可以用在这里。
2、隐藏查询条件
ProTable 默认会显示所有列的查询条件,如果你想隐藏指定列的查询条件,可以在列配置项里添加 hideInSearch:
const columns = [
{
title: '审批单号',
key: 'showTime',
dataIndex: 'showTime',
valueType: 'text',
hideInSearch: true, //隐藏查询条件
},
];
或者如果想直接隐藏整个查询表单的话,可以在 ProTable 上关闭 search 项:
<ProTable
search={false}// 不显示搜索表单
columns={columns}
request={getData}
rowKey="id"
/>
3、查询默认值
你可以通过列表项的 initialValue 来给查询表单项设置默认值:
const columns = [
{
title: '申请日期',
dataIndex: 'applyDate',
valueType: 'date',
align: 'center',
initialValue: '2021-7-1',// 设置默认值
},
// ...
];
4、列宽调整
ProTable 默认会等分所有列,想调整指定列宽的话可以修改列配置的 width 属性,支持百分比和数字。
// 表格行配置项
const columns = [
{
title: '企业名称',
dataIndex: 'corName',
width: '70%', // 设置为百分比
},
{
title: '申请日期',
dataIndex: 'applyDate',
valueType: 'date',
width: 240, // 设置为固定值
}
];
5、查询条件顺序调整
ProTable 默认按照列配置的索引排列查询条件,你可以通过指定列配置项中的 order 来调整查询条件的顺序,其值越大就越靠前:
const columns = [
{
title: '审批单号',
key: 'showTime',
dataIndex: 'showTime',
valueType: 'text',
order: 9,
},
{
title: '任务状态',
key: 'showTime3',
dataIndex: 'showTime3',
valueType: 'select',
order: 10,
valueEnum: {
open: {
text: '审核中',
status: 'Error',
},
closed: {
text: '已完成',
status: 'Success',
},
processing: {
text: '已作废',
status: 'Processing',
},
submited: {
text: '待提交',
status: 'Processing',
},
},
},
];
6、查询条件长度调整
你可以通过指定列配置的 colSize 项来调整具体查询条件的长度,官方介绍如下:
默认情况下一个 colSize 的长度就是 8 span,那么也就是说 colSize: 4 时就可以占满一行:
const columns = [
{
title: '审批单号',
key: 'showTime',
dataIndex: 'showTime',
valueType: 'text',
colSize: 4,
order: 9,
},
//...
];
注意这个值没必要是整数,你可以设置为 0.5 来将其缩短,但是要注意最后相乘得到的 span 值最好是个整数。
7、时间查询条件改为范围
默认的 valueType: 'date' 只会显示单个日期选择器,所以我们需要使用其他方法来实现这个需求,具体做法也很简单,把表格列的查询项关掉,然后放置一个时间范围的查询条件,注意时间范围使用 hideInTable 参数让它不会显示在表格里:
// 表格行配置项
const columns = [
{
title: '申请日期',
dataIndex: 'applyDate',
valueType: 'date',
hideInSearch: true
},
{
title: '申请日期',
dataIndex: 'applyDateRange',
valueType: 'dateRange',
fieldProps: { placeholder: ['开始时间', '结束时间'] },
hideInTable: true
},
];
然后你就可以在 request 里处理他们:
const getData = async (params) => {
const query = {
...params,
applyDateStart: (params.applyDateRange || [])[0],
applyDateEnd: (params.applyDateRange || [])[1]
};
delete query.applyDateRange;
// 发起请求 ...
};
ProForm
ProForm 的好处是封装了不同的表单外观,你只需要切换一个字段就可以把页面表单切换成弹出表单或者抽屉表单。除此之外还封装了提交和重置行为、以及对常用的表单项都进行了封装。
1、基础流程
ProTable 的用法更加简单,在 ProForm 标签里插入封装好的 表单项。然后给 onFinish 设置一个函数即可,这个函数会接受到 通过校验 的表单项,然后你就可以在这里访问后端进行提交了。
import ProForm, {
ProFormRadio,
ProFormText,
ProFormDatePicker,
} from '@ant-design/pro-form';
const PolicyDetail = (props) => {
// 只有通过校验之后才会触发这个方法
const onSubmit = async (values) => {
console.log(values);
};
return (
<ProForm onFinish={onSubmit}>
<ProFormText
name="name"
label="名称"
placeholder="请输入名称"
/>
<ProFormRadio.Group
name="status"
label="状态"
options={[
{ label: '已生效', value: '已生效' },
{ label: '已作废', value: '已作废' }
]}
rules={[{ required: true, message: '状态不能为空' }]}
/>
<ProFormDatePicker
name="publishTime"
label="时间"
placeholder="请选择时间"
rules={[{ required: true, message: '时间不能为空' }]}
/>
</ProForm>
);
};
注意,在 ProForm 中,select, checkbox, radio, radioButton 这些表单项都支持通过 options 参数配置选项内容,其值为 { value: '', label: ''} 格式的数组。具体介绍可以看 这里。
注意,所有的 ProForm 表单组件都是用 Form.Item + 对应的组件封装的来的,都支持使用 fieldProps 属性来支持设置输入组件的 props。
也就是说,fieldProps 参数里的属性都会被透传给内部的输入组件,而直接设置给 ProForm 表单组件的字段会被透传给 Form.Item。切记切记,不要一看到表单项列表里一点属性都没贴就觉得这玩意没法用了。
2、对齐提交按钮
大多数表单开发的习惯都是底部的操作按钮组和字段输入框对齐,但如果你给 form 配置了 layout="horizontal" 和 labelCol={{ span: 4 }} 后就会发现,底部的按钮组还是左侧开始的。
解决这个对齐问题需要用到 ProForm 的 submitter 属性,而其中的 render 函数则可以控制底部按钮组的渲染,这个函数的第二个入参是一个数组,其元素分别是已经渲染好的重置和提交按钮,如果你有需要的话也可以在这里进行更复杂的自定义行为:
<ProForm
submitter={{
render: (_, dom) => (
<Form.Item wrapperCol={{ offset: 4 }}>
<Space>{dom}</Space>
</Form.Item>
),
}}
// ...
>
{/* ... */}
</ProForm>
注意我上面 wrapperCol 的 offset 是 4,你需要根据你的 ProForm 配置自行调整。
3、数据回填
想回填数据的话需要用到 ProForm 的 initialValues,整个表单的数据都应该在这里设置。注意在数据获取到之前不能渲染表单,不然初始值就无效了。
import React, { useState, useEffect } from 'react';
import ProForm from '@ant-design/pro-form';
import { Skeleton } from 'antd';
import { isEmpty } from 'lodash';
import { getDetail } from '@/service';
const Detail = () => {
// 详情数据
const [detail, setDetail] = useState({});
// 获取详情
useEffect(async () => {
const { data } = await getDetail();
setDetail(data);
}, []);
const loadingPage = isEmpty(detail);
// 数据获取到之前展示加载动画,让 form 渲染时肯定可以得到初始值
return loadingPage ? (
<Skeleton active />
) : (
<ProForm initialValues={detail}>
{/* ... */}
</ProForm>
)
};
我注意到有很多人在回填表单数据的时候喜欢用 form.setFieldsValue 设置,但是这么做是不对的,一方面在数据抵达的时候 form 表单项可能还没加载出来,另一方面使用 initialValues 可以让重置按钮可以恢复到初始值,而不是重置成全空表单。
4、表单项联动
表单里经常会出现如下这种表单项联动的需求:
ProComponent 中提供了 ProFormDependency 组件可以响应式的处理这种需求:
import ProForm, { ProFormRadio, ProFormDependency } from '@ant-design/pro-form';
<ProFormRadio.Group
name="status"
label="结论"
options={[
{ label: '审核通过', value: 1 },
{ label: '审核不通过', value: 2 }
]}
/>
<ProFormDependency name={['status']}>
{({ status }) => {
if (!status || status === 1) return null;
return (<ProFormTextArea
name="refuseReason"
label="驳回原因"
placeholder="请填写驳回原因"
/>);
}}
</ProFormDependency>
ProFormDependency 在 name 字段里绑定的值变更后会自动触发 children 里的函数进行渲染。
欧窝
更多用法自己探索