React Antd ProTable 如何设置类似于Excel的筛选框
目标:在web页面的table表格中完成类似于EXCEL的Filter筛选功能。
示例图:点击标题列上方的漏斗状图标,即可对数据进行筛选。
ProTable 前景提要
ProTable API中有说明,是有filter筛选功能的
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
filters | 表头的筛选菜单项 | object[] | - | - |
onFilter | 本地模式下,确定筛选的运行函数 | function | - | - |
个人理解:
filters 设置被筛选的数据
,数据形式是object
onFilter 设置筛选的函数方法
就是自定义一个函数方法用于筛选
理论阶段
根据 前景提要可知,设置筛选需要两个设置。
1.数据准备
-
既然要筛选,那必须是所有数据在里面,且是去除重复后的数据。这样子才算筛选。
那重点就是数据去重
,存储
了 -
可以看到我是有多列需要筛选,那还是抽象封装一个方法数据
去重,和存储的方法
来调用方便低调用和维护。
2.筛选函数
-
就是你选择了筛选框的数据,你要自定义匹配方式,成功就是true,失败就是false。
页面就会显示匹配成功的数据。 -
也是封装方法都用这个匹配方法即可
实践阶段
1.数据准备
- 首先在ProTable中使用request获取数据,调用生成数据方法
request={async (params, sorter, filter) => {
const r = await queryData(current_table, { ...params, sorter, filter });
//获取的数据为r,若有数据则,生成筛选数据。
if (r?.data) {
generateFilterOptions(r.data, {
period: 'period',
end_customer: 'end_customer',
customer_name: 'customer_name',
});
}
- 编写生成数据方法generateFilterOptions
/**
3. data 原数据 propertyMappings 筛选模板
*/
function generateFilterOptions(
data: any[],
propertyMappings: { [key: string]: string },
handleNullForKeys?: string[],
): void {
const groupedOptions: { [key: string]: Option[] } = {};
// 遍历数据,直接构建分组选项
data.forEach((item) => {
Object.entries(propertyMappings).forEach(([targetKey, sourceKey]) => {
let value = item[sourceKey];
if (handleNullForKeys?.includes(targetKey) && value === null) value = '';
if (!groupedOptions[targetKey]) {
groupedOptions[targetKey] = [];
}
// 确保每个值只添加一次,利用 Set 去重
const valueSet = new Set(groupedOptions[targetKey].map((option) => option.value));
if (!valueSet.has(value)) {
groupedOptions[targetKey].push({ key: targetKey, text: String(value), value });
}
});
});
// 将生成的选项设置到状态中
setFilterOptions(groupedOptions);
}
- 用useState存储数据
const [filterOptions, setFilterOptions] = useState<{ [key: string]: Option[] }>({});
- 可以看一下groupedOptions的数据格式,最后需要的就是
{text:‘2023-01’,value:‘2023-01’} 前面的key是用于不同列分组的
2.准备筛选函数
// 通用的过滤函数
const genericOnFilter = (dataIndex: string) => (value: any, record: any) => {
if (value !== null) {
if (value === '') {
return record[dataIndex] === '';
}
if (record[dataIndex] !== null && (typeof value === 'string' || typeof value === 'number')) {
return String(record[dataIndex]).indexOf(String(value)) === 0;
}
} else {
return record[dataIndex] === null;
}
return false;
};
因为null可能或出错,还有空字符串不能使用indexof所以写出这样。
value 是筛选选中的数据,record[dataIndex]是列的数据.
匹配上需要显示的数据就返回true
,不需要的就返回false
3.开始使用
上面所说的API都是ProTable 的column API
const columns: ProColumns<UserDetails>[] = [
{
title: 'Period',
dataIndex: 'period',
filters: filterOptions['period'],
onFilter: genericOnFilter('period'),
},
{
title: 'End Customer',
dataIndex: 'end_customer',
filters: filterOptions['end_customer'],
onFilter: genericOnFilter('end_customer'),
},
{
title: 'Customer name',
dataIndex: 'customer_name',
filters: filterOptions['customer_name'],
onFilter: genericOnFilter('customer_name'),
},
.....
结束
理论上应该讲完了,可能还有更方便快捷的方法。
有疑问或想法可以评论区留言。