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'),},.....
結束
理論上應該講完了,可能還有更方便快捷的方法。
有疑問或想法可以評論區留言。