前言
TDesign的Table组件默认支持input筛选,但是Antdesign并没有,需要通过filterDropdown
自定义筛选
封装filterDropdown
接收两个参数
- type:使用什么方式筛选
- placeholder:Input或RangePicker组件的placeholder
import React from "react"
import { SearchOutlined } from "@ant-design/icons"
import { Button, Input, Space, DatePicker } from "antd"
const { RangePicker } = DatePicker
const getFilterDropdown =
(type, placeholder) =>
({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => {
if (type === "input") {
return (
<div style={{ padding: 8 }}>
<Input
placeholder={placeholder}
value={selectedKeys[0]}
onChange={(e) =>
setSelectedKeys(
e.target.value ? [e.target.value, "InputTableFilter"] : []
)
}
onPressEnter={() => confirm()}
style={{ marginBottom: 8, display: "block" }}
/>
<Space>
<Button
type="primary"
onClick={() => confirm()}
icon={<SearchOutlined />}
size="small"
>
搜索
</Button>
<Button
onClick={() => {
clearFilters?.()
setSelectedKeys([])
confirm()
}}
size="small"
>
重置
</Button>
</Space>
</div>
)
}
// 日期范围选择器的筛选
if (type === "time") {
const handleDateChange = (_dates, dateStrings) => {
setSelectedKeys(
dateStrings.length ? [...dateStrings, "DateTableFilter"] : []
)
confirm()
}
return (
<div style={{ padding: 8 }}>
<RangePicker
onChange={handleDateChange}
showTime
format="YYYY-MM-DD HH:mm:ss"
/>
</div>
)
}
return null // 确保在 type 不为 input 或 time 时有返回值
}
export default getFilterDropdown
返回筛选结果时会在列表末尾插入一个标识,如input对应InputTableFilter、time对应DateTableFilter,这个标识用于确认是否由自定义筛选触发以及采用何种自定义筛选方式。
使用时
filterDropdown: getFilterDropdown("input", "请输入检索条件进行查询")
filterDropdown: getFilterDropdown("time", "请选择时间范围")
确保筛选后参数
筛选是通过后端接口实现,本文示例参数格式为{page:1,size:10,search:[{key1:value1},{key2:value2},{...}...]}
,其中search为表格筛选条件(对象数组),它的key对应表格中对应列的key。
同时筛选不止表格组件内实现,表格外也有Input可以对表格进行筛选。
封装函数,确保search中元素对象的唯一性
- searchArray:筛选参数(本文中为search)
- key:搜索的列
- value:搜索条件
const updateTableFilter = (searchArray, key, value) => {
const foundIndex = searchArray.findIndex((item) => key in item)
if (value === null) {
// 删除对应的对象
if (foundIndex !== -1) {
searchArray.splice(foundIndex, 1)
}
} else if (foundIndex !== -1) {
// 更新已存在的对象
searchArray[foundIndex] = { ...searchArray[foundIndex], [key]: value }
} else {
// 添加新的对象
searchArray.push({ [key]: value })
}
return searchArray
}
Table组件的筛选通过onChange
触发,filters参数会返回对象,其中包括所有可筛选项的值,如未针对某列筛选,那么对应列的value为null。
封装函数,对filters进行处理
- filters:Table组件onChange时的参数filters
- prevSearch:当前筛选条件
const processFilters = (filters, prevSearch) => {
let searchArray = [...prevSearch] // 确保不直接修改原数组
Object.entries(filters).forEach(([key, value]) => {
let filterValue = value
if (Array.isArray(value) && value.length > 0) {
const filterFlag = value[value.length - 1] // 尝试获取自定义筛选的标识
// 处理自定义筛选
if (filterFlag === "InputTableFilter") {
filterValue = value[0] // 去掉标识
} else if (filterFlag === "DateTableFilter") {
filterValue = value.slice(0, -1) // 去掉标识
}
}
searchArray = updateTableFilter(searchArray, key, filterValue)
})
return searchArray
}
使用时:
表格筛选
const onTableChange = (
{ current, pageSize },
filters
) => {
tableparam = {
...tableparam,
page: current,
size: pageSize,
search: processFilters(filters, tableparam.search),
}
}
表格外部筛选(如输入框)
const onSearch = () => {
tableparam.search = updateTableFilter(
tableparam.search,
"name", // 筛选的key
iptValue // 输入框的值
)
// 刷新表格...
}