FormTable 带筛选的表格
QueryFilter 和 Table 的组合。
中后台 console 项目最常用的组件,用于所有带筛选的列表页。
基本使用
一般配合 BfFormTable.useFormTable
使用。useFormTable
是一个基于 ahooks
useAntdTable 二次封装的自定义 hooks 。
useFormTable 常用配置
多选
multiple: true
缓存
cacheKey: 'xxx-mgt'
此字段会透传给 ahooks
的 useAntdTable
,用于缓存表格的筛选条件和分页信息。注意,值尽量配置全局唯一。
更多配置见 API
配置筛选项、表格列
方式一【推荐】
v0.8.0
之后,我们可以直接在BfFormTable.useFormTable
中配置筛选项和表格列,并带有完善且准确的 ts 类型(sincev1.3.0
),同时表格列添加了ellipsisLimit
和tooltip
两个实用的属性,详见 BfTableColumnType。示例代码:
import { BfFormTable } from '@bud-fe/react-pc-ui';
// ...
const { tableProps, form, search, fieldFilter } = BfFormTable.useFormTable({
// ...
searchFormItems: [
{ type: 'input', name: 'roleName', label: '角色名称', initialValue: 'admin' },
{ type: 'input', name: 'roleLabel', label: '角色标签' },
],
tableColumns: [
{ title: '角色ID', dataIndex: 'roleCode' },
{ title: '角色名称', dataIndex: 'roleName', ellipsisLimit: 5 },
{ title: '最近一次更新时间', dataIndex: 'updateTime', tooltip: '这里显示气泡框' },
],
});
// ...
return (
<>
<BfFormTable
className="form-table"
rowKey="roleCode"
actionBarTitle="角色列表"
actionBar={actionBar}
search={search}
form={form}
fieldFilter={fieldFilter}
{...tableProps}
/>
</>
);
方式二
v0.8.0
之前,我们只能通过定义变量,自己引入类型做约束,然后传递给BfFormTable
的searchFormCol
和tableCol
,比如:
import { BfFormTable, EllipsisTableText, SearchFormItemType } from '@bud-fe/react-pc-ui';
import type { ColumnsType } from 'antd/lib/table';
// ...
const tableCol: ColumnsType<any> = [
{ title: '岗位ID', dataIndex: 'postId' },
{ title: '岗位名称', dataIndex: 'postName', render: EllipsisTableText(20) },
];
const searchFormCol: SearchFormItemType[] = [
{ type: 'input', name: 'postInfo', label: '岗位信息', placeholder: '请输入岗位ID/岗位名称' },
];
// ...
return (
<>
<BfFormTable
rowKey="id"
tableCol={tableCol}
searchFormCol={searchFormCol}
actionBar={actionBar}
search={search}
form={form}
{...tableProps}
/>
</>
);
配置操作列
中后台 console 项目中的列表页,基本上最后一列都是“操作”,这部分的代码高频且重复,所以我们提供了一个 BfFormTable.useActionColumn
的 hooks 来简化操作列的配置,详见 API。
import { BfFormTable } from '@bud-fe/react-pc-ui';
import type { ITableItem } from '@/service/demo-service';
import Auth from '@/components/auth';
// ...
const actionsColumn = BfFormTable.useActionsColumn<ITableItem>({
// 如果需要做按钮权限控制的,需要传递一个 Auth 组件用于包裹按钮,否则不需要传递
AuthWrapperComp: Auth,
// 定义操作按钮
items: (record) => {
return [
{
action: 'view',
label: '查看',
// 按钮权限控制的 key
authKey: 'demo-view',
// 每个按钮的点击事件,如果不传递,则默认会调用 onActionBtnClick
// onClick: () => {
// message.info(`查看:${JSON.stringify(record)}`);
// },
},
{
action: 'audit',
label: '审核',
authKey: 'demo-audit',
// 按钮是否可见,一般用于根据当前行数据的状态动态显隐按钮,与按钮权限无关。如果不传递,则默认为 true
visible: record.roleCode === '1',
// 按钮无权限时的展示的内容,如果不传递,则默认为 null
fallback: 123,
},
];
},
// 全局的按钮点击事件。优先级次于每个按钮配置中的 onClick
onActionBtnClick(item, record) {
message.info(`item: ${JSON.stringify(item)}; record: ${JSON.stringify(record)}`);
},
});
const { tableProps, form, search, fieldFilter } = BfFormTable.useFormTable({
// ...
tableColumns: [
{ title: '角色ID', dataIndex: 'roleCode' },
{ title: '角色名称', dataIndex: 'roleName', ellipsisLimit: 5 },
{ title: '最近一次更新时间', dataIndex: 'updateTime', tooltip: '这里显示气泡框' },
// useActionsColumn 返回的是一个表格列的配置对象,直接加到表格列配置数组末尾即可
actionsColumn,
],
});
// ...
常见问题
1. 如何获取当前筛选项的数据
所有获取方式的前提是 查询 过一次
- 方式一
const { params } = BfFormTable.useFormTable({ ... });
console.log(params);
/**
* params 是 useAntdTable 返回的字段,结构是一个三个元素的数组,比如:
* [
* { pageSize: 10, current: 1}, // 分页参数
* { name: 'admin', tag: undefined, status: '0' }, // 筛选参数
* { allFormData: {…}, type: 'simple' } // allFormData 为所有参数
* ]
*/
- 方式二
const { form } = BfFormTable.useFormTable({ ... });
console.log(form.getFieldsValue()); // 不包含分页参数
2. 如何自定义日期格式
由于 antd 中 DatePicker
的 format
属性只能自定义日期的“显示”格式,所以 FormTable
中扩展了 format
属性的功能,传入后也会格式化对应的 value。
const searchFormCol: SearchFormItemType[] = useMemo(() => {
return [
// ...
{
type: 'date',
name: 'date',
label: '日期',
fieldProps: {
format: 'yyyy-MM-DD', // 也可传入函数。类型和 DatePicker 的 format 属性一致
},
},
];
}, []);
当请求接口时,入参将会是 date: 'yyyy-MM-DD'
这种格式,而不是默认的 moment 对象
3. 日期范围的入参需要拆分成两个字段
由于百威关于日期范围相关的 API 一般都是定义两个字段让前端来传,但是前端都是一个表单项对应一个字段,所以之前(before v0.4.0
)都是需要使用者在传入 useFormTable
的 service 中自己去拆分,很不方便。
为了解决这个问题,当 type: 'dateRange'
时,我们还可以传入一个 nameArr
字段,表示要拆分的字段名。
同时,如果要在请求接口时移除原来 name
对应的字段,还需要将 useFormTable
返回的 fieldFilter
透传给 FormTable
,比如:
const { fieldFilter } = BfFormTable.useFormTable({
// ...
});
const searchFormCol: SearchFormItemType[] = useMemo(() => {
return [
// ...
{
type: 'dateRange',
name: 'dateRange',
// 要拆分的字段名
nameArr: ['startDate', 'endDate'],
label: '日期范围',
fieldProps: {
format: 'yyyy-MM-DD',
},
},
];
}, []);
return (
<BfFormTable
{...}
searchFormItems={searchFormCol}
fieldFilter={fieldFilter}
/>
);
当请求接口时,日期范围的入参将会是 {startDate: 'yyyy-MM-DD', endDate: 'yyyy-MM-DD'}
,而且移除了 dateRange: ['yyyy-MM-DD', 'yyyy-MM-DD']
API
FormTable
其余 props 请参考 Table
API
useFormTable
其余 props 请参考 ahooks
useAntdTable
useActionsColumn
SearchFormItemType
其余 props 请参考 ProFormFields
API