ProTable - 高级表格

ProTable 的诞生是为了解决项目中需要写很多 table 的样板代码的问题,所以在其中做了封装了很多常用的逻辑。这些封装可以简单的分类为预设行为与预设逻辑。

依托于 ProForm 的能力,ProForm 拥有多种形态,可以切换查询表单类型,设置变形成为一个简单的 Form 表单,执行新建等功能。

layout\n

若您是内网用户,欢迎使用我们的 TechUI Studio 可视化配置生成初始代码。

何时使用

当你的表格需要与服务端进行交互或者需要多种单元格样式时,ProTable 是不二选择。

代码演示

查询表格

查询(无按钮)表格

无查询表单

轻量筛选替换查询表单

无 ToolBar 的表格

必填的查询表单

尽量使用 initialValue 来解决问题,必填项挫败感比较强

嵌套表格

左右结构

表格批量操作

通过 formRef 来操作查询表单

RTL (النسخة العربية)

RTL means right-to-left.

受控的表格设置栏

可以默认隐藏某些栏,但是在操作栏中可以选择

表格轮询

dateFormatter - 日期格式化

搜索表单自定义

当内置的表单项无法满足我们的基本需求,这时候我们就需要来自定义一下默认的组件,我们可以通过 fieldPropsrenderFormItem 配合来使用。

fieldProps 可以把 props 透传,可以设置 select 的样式和多选等问题。

renderFormItem 可以完成重写渲染逻辑,传入 item 和 props 来进行渲染,需要注意的是我们必须要将 props 中的 valueonChange 必须要被赋值,否则 form 无法拿到参数。如果你需要自定义需要先了解 antd 表单的工作原理

renderFormItem: (_, { type, defaultRender, formItemProps, fieldProps, ...rest }, form) => {
if (type === 'form') {
return null;
}
const status = form.getFieldValue('state');
if (status !== 'open') {
return (
// value 和 onchange 会通过 form 自动注入。
<Input
// 组件的配置
{...fieldProps}
// 自定义配置
placeholder="请输入test"
/>
);
}
return defaultRender(_);
};

renderFormItem 的定义, 具体的值可以打开控制台查看。

renderFormItem?: (
item: ProColumns<T>,
config: {
value?: any;
onSelect?: (value: any) => void;
type: ProTableTypes;
defaultRender: (newItem: ProColumns<any>) => JSX.Element | null;
},
form: FormInstance,
) => JSX.Element | false | null;

FAQ

为什么不能自己设置 value 和 onchange

被 ProTable 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:

  • 你不再需要也不应该用 onChange 来做数据收集同步(你可以使用 Form 的 onValuesChange),但还是可以继续监听 onChange 事件。

  • 你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。

  • 你不应该用 setState,可以使用 form.setFieldsValue 来动态改变表单值。

为什么设置 defaultValue 不生效?#

因为 ProTable 子组件会转为受控模式。因而 defaultValue 不会生效。你需要在 Form 上通过 initialValues 设置默认值。

表单操作自定义

Toolbar 自定义

使用 toolbar属性扩展配置工具栏渲染。

表格主体自定义

卡片表格

有些业务有自己的定制逻辑,可以不完全遵循 ProTable 的设计规则,但可以利用 ProTable 的 API 实现。如通过 cardProps 配置卡片属性,通过 headTitle 配置行动点在左侧。

国际化相关的配置

ProTable 内置了国际化的支持,作为一个文本量比较少的组件,我们可以自行实现国际化,成本也很低。

这里是全量的文本

const enLocale = {
tableForm: {
search: 'Query',
reset: 'Reset',
submit: 'Submit',
collapsed: 'Expand',
expand: 'Collapse',
inputPlaceholder: 'Please enter',
selectPlaceholder: 'Please select',
},
alert: {
clear: 'Clear',
},
tableToolBar: {
leftPin: 'Pin to left',
rightPin: 'Pin to right',
noPin: 'Unpinned',
leftFixedTitle: 'Fixed the left',
rightFixedTitle: 'Fixed the right',
noFixedTitle: 'Not Fixed',
reset: 'Reset',
columnDisplay: 'Column Display',
columnSetting: 'Settings',
fullScreen: 'Full Screen',
exitFullScreen: 'Exit Full Screen',
reload: 'Refresh',
density: 'Density',
densityDefault: 'Default',
densityLarger: 'Larger',
densityMiddle: 'Middle',
densitySmall: 'Compact',
},
};
// 生成 intl 对象
const enUSIntl = createIntl('en_US', enUS);
import { ConfigProvider } from '@ant-design/pro-provide';
// 使用
<ConfigProvider
value={{
intl: enUSIntl,
}}
>
<ProTable />
</ConfigProvider>;

使用自带 keyWords 搜索的 table

值类型示例

valueType - 日期类

valueType - 数字类

valueType - 样式类

valueType - 选择类

自定义错误边界

API

ProTable 在 antd 的 Table 上进行了一层封装,支持了一些预设,并且封装了一些行为。这里只列出与 antd Table 不同的 api。

request

request 是 ProTable 最重要的 API,request 会接收一个对象。对象中必须要有 datasuccess,如果需要手动分页 total 也是必需的。request 会接管 loading 的设置,同时在查询表单查询和 params 参数发生修改时重新执行。同时 查询表单的值和 params 参数也会带入。以下是一个例子:

<ProTable<DataType, Params>
// params 是需要自带的参数
// 这个参数优先级更高,会覆盖查询表单的参数
params={params}
request={async (
// 第一个参数 params 查询表单和 params 参数的结合
// 第一个参数中一定会有 pageSize 和 current ,这两个参数是 antd 的规范
params: T & {
pageSize: number;
current: number;
},
sort,
filter,
) => {
// 这里需要返回一个 Promise,在返回之前你可以进行数据转化
// 如果需要转化参数可以在这里进行修改
const msg = await myQuery({
page: params.current,
pageSize: params.pageSize,
});
return {
data: msg.result,
// success 请返回 true,
// 不然 table 会停止解析数据,即使有数据
success: boolean,
// 不传会使用 data 的长度,如果是分页一定要传
total: number,
};
}}
/>

列配置中也支持 request,但是只有几种 valueType 支持。

ProTable

属性描述类型默认值
request获取 dataSource 的方法(params?: {pageSize,current},sort,filter) => {data,success,total}-
params用于 request 查询的额外参数,一旦变化会触发重新加载object-
postData对通过 request 获取的数据进行处理(data: T[]) => T[]-
defaultData默认的数据T[]-
dataSourceTable 的数据,protable 推荐使用 request 来加载T[]-
onDataSourceChangeTable 的数据发生改变时触发(dataSource: T[]) => void-
actionRefTable action 的引用,便于自定义触发MutableRefObject<ActionType>-
formRef可以获取到查询表单的 form 实例,用于一些灵活的配置MutableRefObject<FormInstance>-
toolBarRender渲染工具栏,支持返回一个 dom 数组,会自动增加 margin-right(action) => ReactNode[]-
onLoad数据加载完成后触发,会多次触发(dataSource: T[]) => void-
onLoadingChangeloading 被修改时触发,一般是网络请求导致的(loading:boolean)=>void-
onRequestError数据加载失败时触发(error) => void-
tableClassName封装的 table 的 classNamestring-
tableStyle封装的 table 的 styleCSSProperties-
optionstable 工具栏,设为 false 时不显示.传入 function 会点击时触发{{ density?: boolean, fullScreen: boolean | function, reload: boolean | function, setting: boolean | SettingOptionType }}{ fullScreen: false, reload: true, setting: true }
search是否显示搜索表单,传入对象时为搜索表单的配置false | SearchConfig-
defaultSize默认的 sizeSizeType-
dateFormatter转化 moment 格式数据为特定类型,false 不做转化"string" | "number" | ((value: Moment, valueType: string) => string | number) | false"string"
beforeSearchSubmit搜索之前进行一些修改(params:T)=>T-
onSizeChangetable 尺寸发生改变(size: 'default' | 'middle' | 'small') => void-
typepro-table 类型"form"-
formantd form 的配置FormProps-
onSubmit提交表单时触发(params: U) => void-
onReset重置表单时触发() => void-
columnEmptyText空值时的显示,不设置时显示 -, false 可以关闭此功能string | falsefalse
tableRender自定义渲染表格函数(props,dom,domList:{ toolbar,alert,table}) => ReactNode-
toolbar透传 ListToolBar 配置项ListToolBarProps-
tableExtraRender自定义表格的主体函数(props: ProTableProps<T, U>, dataSource: T[]) => ReactNode;-
manualRequest是否需要手动触发首次请求, 配置为 true 时不可隐藏搜索表单booleanfalse
editable可编辑表格的相关配置TableRowEditable-
cardBorderedTable 和 Search 外围 Card 组件的边框boolean | {search?: boolean, table?: boolean}false
debounceTime防抖时间number10
revalidateOnFocus窗口聚焦时自动重新请求booleantrue
columnsState受控的列状态,可以操作显示隐藏columnsStateType-
ErrorBoundary自带了错误处理功能,防止白屏,ErrorBoundary=false 关闭默认错误边界ReactNode内置 ErrorBoundary

RecordCreator

属性描述类型默认值
record需要新增的行数据,一般来说包含唯一 keyT{}
position行增加在哪里,开始或者末尾top | bottombottom
(...buttonProps)antd 的 ButtonPropsButtonProps

ColumnsStateType

属性描述类型默认值
defaultValue列状态的默认值,只有初次生效Record<string, ColumnsState>;-
value列状态的值,支持受控模式Record<string, ColumnsState>;-
onChange列状态的值发生改变之后触发(value:Record<string, ColumnsState>)=>void-
persistenceKey持久化列的 key,用于判断是否是同一个 tablestring | number-
persistenceType持久化列的类类型, localStorage 设置在关闭浏览器后也是存在的,sessionStorage 关闭浏览器后会丢失localStorage | sessionStorage-

Search 搜索表单

属性描述类型默认值
filterType过滤表单类型'query' | 'light''query'
searchText查询按钮的文本string查询
resetText重置按钮的文本string重置
submitText提交按钮的文本string提交
labelWidth标签的宽度'number' | 'auto'80
span配置查询表单的列数'number' | 'ColConfig'defaultColConfig
className封装的搜索 Form 的 classNamestring-
collapseRender收起按钮的 render(collapsed: boolean,showCollapseButton?: boolean,) => ReactNode-
defaultCollapsed默认是否收起booleantrue
collapsed是否收起boolean-
onCollapse收起按钮的事件(collapsed: boolean) => void;-
optionRender自定义操作栏((searchConfig,formProps,dom) => ReactNode[])|false-
showHiddenNum是否显示收起之后显示隐藏个数booleanfalse

ColConfig

const defaultColConfig = {
xs: 24,
sm: 24,
md: 12,
lg: 12,
xl: 8,
xxl: 6,
};

菜单栏 options 配置

export type OptionsType =
| ((e: React.MouseEvent<HTMLSpanElement>, action?: ActionType) => void)
| boolean;
export type OptionConfig = {
density?: boolean;
fullScreen?: OptionsType;
reload?: OptionsType;
setting?: boolean | SettingOptionType;
search?: (OptionSearchProps & { name?: string }) | boolean;
};
export type SettingOptionType = {
draggable?: boolean;
checkable?: boolean;
checkedReset?: boolean;
listsHeight?: number;
extra?: React.ReactNode;
children?: React.ReactNode;
};

ActionRef 手动触发

有时我们要手动触发 table 的 reload 等操作,可以使用 actionRef,可编辑表格也提供了一些操作来帮助我们更快的实现需求。

interface ActionType {
reload: (resetPageIndex?: boolean) => void;
reloadAndRest: () => void;
reset: () => void;
clearSelected?: () => void;
startEditable: (rowKey: Key) => boolean;
cancelEditable: (rowKey: Key) => boolean;
}
const ref = useRef<ActionType>();
<ProTable actionRef={ref} />;
// 刷新
ref.current.reload();
// 刷新并清空,页码也会重置,不包括表单
ref.current.reloadAndRest();
// 重置到默认值,包括表单
ref.current.reset();
// 清空选中项
ref.current.clearSelected();
// 开始编辑
ref.current.startEditable(rowKey);
// 结束编辑
ref.current.cancelEditable(rowKey);

Columns 列定义

请求远程数据比较复杂,详细可以看这里

属性描述类型默认值
title与 antd 中基本相同,但是支持通过传入一个方法ReactNode | ((config: ProColumnType<T>, type: ProTableTypes) => ReactNode)-
tooltip会在 title 之后展示一个 icon,hover 之后提示一些信息string-
ellipsis是否自动缩略boolean-
copyable是否支持复制boolean-
valueEnum值的枚举,会自动转化把值当成 key 来取出要显示的内容valueEnum-
valueType值的类型,会生成不同的渲染器valueTypetext
order查询表单中的权重,权重大排序靠前number-
fieldProps查询表单的 props,会透传给表单项,如果渲染出来是 Input,就支持 input 的所有 props,同理如果是 select,也支持 select 的所有 props。也支持方法传入(form,config)=>Record | Record-
formItemProps传递给 Form.Item 的配置,可以配置 rules,但是默认的查询表单 rules 是不生效的。需要配置 ignoreRules(form,config)=>formItemProps | formItemProps-
renderText类似 table 的 render,但是必须返回 string,如果只是希望转化枚举,可以使用 valueEnum(text: any,record: T,index: number,action: UseFetchDataAction<T>) => string-
render类似 table 的 render,第一个参数变成了 dom,增加了第四个参数 action(text: ReactNode,record: T,index: number,action: UseFetchDataAction<T>) => ReactNode | ReactNode[]-
renderFormItem渲染查询表单的输入组件(item,{ type, defaultRender, formItemProps, fieldProps, ...rest },form) => ReactNode-
search配置列的搜索相关,false 为隐藏false | { transform: (value: any) => any }true
search.transform转化值的 key, 一般用于时间区间的转化(value: any) => any-
editable在编辑表格中是否可编辑的,函数的参数和 table 的 render 一样false | (text: any, record: T,index: number) => booleantrue
colSize一个表单项占用的格子数量, 占比= colSize*spancolSize 默认为 1 ,span 为 8,spanform={{span:8}} 全局设置的number-
hideInSearch在查询表单中不展示此项boolean-
hideInTable在 Table 中不展示此列boolean-
hideInForm在 Form 中不展示此列boolean-
hideInDescriptions在 Descriptions 中不展示此列boolean-
filters表头的筛选菜单项,当值为 true 时,自动使用 valueEnum 生成boolean | object[]false
onFilter筛选表单,为 true 时使用 ProTable 自带的,为 false 时关闭本地筛选(value, record) => boolean | falsefalse
request从服务器请求枚举request-
initialValue查询表单项初始值any-
disable列设置中disabled的状态boolean | { checkbox: boolean; }-

valueType 值类型

ProTable 封装了一些常用的值类型来减少重复的 render 操作,配置一个 valueType 即可展示格式化响应的数据。

批量操作

与 antd 相同,批量操作需要设置 rowSelection 来开启,与 antd 不同的是,pro-table 提供了一个 alert 用于承载一些信息。你可以通过 tableAlertRendertableAlertOptionRender 来对它进行自定义。设置或者返回 false 即可关闭。

属性描述类型默认值
alwaysShowAlert总是展示 alert,默认无选择不展示(rowSelection内置属性)boolean-
tableAlertRender自定义批量操作工具栏左侧信息区域, false 时不显示({ selectedRowKeys: Key[], selectedRows: T[], onCleanSelected: ()=>void }) => ReactNode)|false-
tableAlertOptionRender自定义批量操作工具栏右侧选项区域, false 时不显示({ selectedRowKeys: Key[], selectedRows: T[], onCleanSelected: ()=>void }) => ReactNode)|false-

搜索表单

ProTable 会根据列来生成一个 Form,用于筛选列表数据,最后的值会根据通过 request 的第一个参数返回,看起来就像。

<ProTable request={(params,sort,filter)=>{ all params}}>

按照规范,table 的表单不需要任何的必选参数,所有点击搜索和重置都会触发 request来发起一次查询。

Form 的列是根据 valueType 来生成不同的类型,详细的值类型请查看通用配置

valueType 为 index indexBorder option 和没有 dataIndex 和 key 的列将会忽略。

列表工具栏

用于自定义表格的工具栏部分。

代码演示

ListToolBarProps

列表和表格的工具栏配置属性

参数说明类型默认值
title标题ReactNode-
subTitle子标题ReactNode-
description描述ReactNode-
search查询区ReactNode | SearchProps-
actions操作区ReactNode[]-
settings设置区(ReactNode | Setting)[]-
filter过滤区,通常配合 LightFilter 使用ReactNode-
multipleLine是否多行展示booleanfalse
menu菜单配置ListToolBarMenu-
tabs标签页配置,仅当 multipleLine 为 true 时有效ListToolBarTabs-

SearchProps 为 antd 的 Input.Search 的属性。

Setting

参数说明类型默认值
icon图标ReactNode-
tooltiptooltip 描述string-
key操作唯一标识string-
onClick设置被触发(key: string)=>void-

ListToolBarMenu

参数说明类型默认值
type类型inline | dropdown | tabdropdown
activeKey当前值string-
items菜单项{ key: string; label: ReactNode }[]-
onChange切换菜单的回调(activeKey)=>void-

ListToolBarTabs

参数说明类型默认值
activeKey当前选中项string-
items菜单项{ key: string; tab: ReactNode }[]-
onChange切换菜单的回调(activeKey)=>void-

TableDropdown

参数说明类型默认值
key唯一标志string-
name内容ReactNode-
(...Menu.Item)antd 的 Menu.ItemMenu.Item-