Web的Ant-Design框架的Table表格组件,用于前端显示表格:当大量结构化的数据需要展示,需要对数据进行排序、搜索、自定义操作等行为时,可以使用Table组件。
1.简单的使用
首先定义数据源dataSource,数组格式,然后定义第一行字段columns,如下
const dataSource = [
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
];
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
];
<Table dataSource={dataSource} columns={columns} />;
2.可选择
在每一行数据的左侧显示勾选框,可以通过rowSelection。其中selectedRowKeys为当前选中项,可通过修改它来控制选中项;onChange绑定选择改变的方法。
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const rowSelection = {
selectedRowKeys,
onChange: handleTableSelectChange,
getCheckboxProps: (record: LinkRecord) => ({
disabled: false,
}),
};
3.筛选和排序
对于列数据筛选,使用列的filters属性来指定需要筛选菜单的列,onFilter 用于筛选当前数据,filterMultiple 用于指定多选和单选。对于一列数据进行排序,通过指定列的 sorter 函数即可启动排序按钮。sorter: function(rowA, rowB) { ... }, rowA、rowB 为比较的两个行数据。sortDirections: ['ascend' | 'descend']改变每列可用的排序方式,切换排序时按数组内容依次切换,设置在 table props 上时对所有列生效。你可以通过设置 ['ascend', 'descend', 'ascend'] 禁止排序恢复到默认状态。可通过使用 defaultSortOrder 属性,设置列的默认排序顺序。
{
title: '日期',
dataIndex: 'Date',
key: 'Date',
width: 120,
sorter: (a, b) => {
const aDate = a.Date ? new Date(a.Date).getTime() : 0;
const bDate = b.Date ? new Date(b.Date).getTime() : 0;
return aDate - bDate;
},
filters: getUniqueDates().map(date => ({
text: date,
value: date,
})),
onFilter: (value, record) => record.Date === value,
render: (value) => (
<Tooltip title={value}>
<span>{value}</span>
</Tooltip>
),
}
定义可控筛选filteredValue和可控排序sortOrder。
const [filteredInfo, setFilteredInfo] = useState<Record<string, FilterValue | null>>({});
const [sortedInfo, setSortedInfo] = useState<SorterResult<DataType>>({});
{
title: 'Name',
dataIndex: 'name',
key: 'name',
filters: [
{ text: 'Joe', value: 'Joe' },
{ text: 'Jim', value: 'Jim' },
],
filteredValue: filteredInfo.name || null,
onFilter: (value: string, record) => record.name.includes(value),
sorter: (a, b) => a.name.length - b.name.length,
sortOrder: sortedInfo.columnKey === 'name' ? sortedInfo.order : null,
ellipsis: true,
}
4.远程加载数据
import { Table } from 'antd';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
import qs from 'qs';
import React, { useEffect, useState } from 'react';
interface DataType {
name: {
first: string;
last: string;
};
gender: string;
email: string;
login: {
uuid: string;
};
}
interface TableParams {
pagination?: TablePaginationConfig;
sortField?: string;
sortOrder?: string;
filters?: Record<string, FilterValue>;
}
const columns: ColumnsType<DataType> = [
{
title: 'Name',
dataIndex: 'name',
sorter: true,
render: name => `${name.first} ${name.last}`,
width: '20%',
},
{
title: 'Gender',
dataIndex: 'gender',
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
width: '20%',
},
{
title: 'Email',
dataIndex: 'email',
},
];
const getRandomuserParams = (params: TableParams) => ({
results: params.pagination?.pageSize,
page: params.pagination?.current,
...params,
});
const App: React.FC = () => {
const [data, setData] = useState();
const [loading, setLoading] = useState(false);
const [tableParams, setTableParams] = useState<TableParams>({
pagination: {
current: 1,
pageSize: 10,
},
});
const fetchData = () => {
setLoading(true);
fetch(`https://randomuser.me/api?${qs.stringify(getRandomuserParams(tableParams))}`)
.then(res => res.json())
.then(({ results }) => {
setData(results);
setLoading(false);
setTableParams({
...tableParams,
pagination: {
...tableParams.pagination,
total: 200,
// 200 is mock data, you should read it from server
// total: data.totalCount,
},
});
});
};
useEffect(() => {
fetchData();
}, [JSON.stringify(tableParams)]);
const handleTableChange = (
pagination: TablePaginationConfig,
filters: Record<string, FilterValue>,
sorter: SorterResult<DataType>,
) => {
setTableParams({
pagination,
filters,
...sorter,
});
};
return (
<Table
columns={columns}
rowKey={record => record.login.uuid}
dataSource={data}
pagination={tableParams.pagination}
loading={loading}
onChange={handleTableChange}
/>
);
};
export default App;
上面代码通过 使用useEffect监听表格属性tableParams变化,来调用fetchData请求数据并展示,并且通过设置setLoading显示正在加载数据的页面 loading 效果。
5.可展开的数据行
可展开的数据行,通过Table的expandable来实现
expandable={{
expandedRowRender: record => <p style={{ margin: 0 }}>{record.description}</p>,//展开后的每一行的显示内容
rowExpandable: record => record.name !== 'Not Expandable',//是否可展开
}}
6.表格的行或者列合并
表头只支持列合并,使用 column 里的 colSpan 进行设置。例如 表头的colSpan: 2, 代表第从这一列开始合并两个表头, 也就是占据两列的宽度;
表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。
{
title: 'Home phone',
colSpan: 2,
dataIndex: 'tel',
onCell: (_, index) => {
if (index === 2) {//第3行(index=2)表示这个单元格要向下合并2行(包括当前行)
return { rowSpan: 2 };
}
//这两个合并到上面的单元格中
if (index === 3) {//第4行(index=3)表示这个单元格不显示,被上方的单元格合并了
return { rowSpan: 0 };
}
return {};
},
},
7.树形数据展示
当数据源的数据包含children会自动展示树形表格,如果不需要或配置为其他字段可以用 childrenColumnName 进行配置。
8.固定表头
用于展示大量数据。需要指定 column 的 width 属性,否则列头和内容可能不对齐。
import { Table } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import React from 'react';
interface DataType {
key: React.Key;
name: string;
age: number;
address: string;
}
const columns: ColumnsType<DataType> = [
{
title: 'Name',
dataIndex: 'name',
width: 150,
},
{
title: 'Age',
dataIndex: 'age',
width: 150,
},
{
title: 'Address',
dataIndex: 'address',
},
];
const data: DataType[] = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
});
}
const App: React.FC = () => (
<Table columns={columns} dataSource={data} pagination={{ pageSize: 50 }} scroll={{ y: 240 }} />
);
export default App;