如何为Material UI EnhancedTable实现全列过滤(不使用DataGrid)
给Material UI EnhancedTable实现列过滤功能
直接上轻量落地方案——在每个列头加小型输入框做实时模糊过滤,不用复杂模态框,快速满足需求:
步骤1:维护过滤状态
在组件中添加状态存储各列的过滤值:
import { useState } from 'react'; // ...其他原有导入 const EnhancedTable = () => { // ...保留原有排序、选中项等状态 const [filters, setFilters] = useState({}); // 结构:{ 列字段名: 过滤文本 }
步骤2:改造表头,添加过滤输入框
在TableHead的每个TableCell里,追加一个小型TextField,绑定对应列的过滤值:
<TableHead> <TableRow> {/* 保留原有选择列(如果存在) */} <TableCell padding="checkbox"> <Checkbox indeterminate={numSelected > 0 && numSelected < rows.length} checked={rows.length > 0 && numSelected === rows.length} onChange={handleSelectAllClick} inputProps={{ 'aria-label': 'select all items' }} /> </TableCell> {/* 遍历列定义,渲染列头+过滤框 */} {columns.map((column) => ( <TableCell key={column.id} align={column.align} padding={column.disablePadding ? 'none' : 'normal'} sortDirection={orderBy === column.id ? order : false} > <TableSortLabel active={orderBy === column.id} direction={orderBy === column.id ? order : 'asc'} onClick={() => handleRequestSort(event, column.id)} > {column.label} {orderBy === column.id ? ( <Box component="span" sx={{ visibility: 'visible' }}>{sortIcon}</Box> ) : ( <Box component="span" sx={{ visibility: 'hidden' }}>{sortIcon}</Box> )} </TableSortLabel> {/* 新增过滤输入框 */} <TextField size="small" placeholder="过滤..." value={filters[column.id] || ''} onChange={(e) => { setFilters(prev => ({ ...prev, [column.id]: e.target.value.trim().toLowerCase() })); }} sx={{ mt: 0.5, width: '100%' }} /> </TableCell> ))} </TableRow> </TableHead>
步骤3:实现过滤逻辑
编写函数对原始数据做模糊匹配过滤:
const getFilteredRows = () => { // 无过滤条件时直接返回原始数据 if (Object.values(filters).every(val => !val)) return rows; return rows.filter(row => { // 所有列的过滤条件都满足才保留该行 return Object.entries(filters).every(([key, filterText]) => { if (!filterText) return true; // 该列无过滤条件,直接通过 const cellValue = row[key]?.toString().toLowerCase(); return cellValue?.includes(filterText); }); }); }; // 在组件内获取过滤后的数据 const filteredRows = getFilteredRows();
步骤4:渲染过滤后的数据
把原来渲染rows的地方替换成filteredRows,比如表格体部分:
<TableBody> {/* 将原rows替换为filteredRows */} {stableSort(filteredRows, getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row, index) => { const isItemSelected = isSelected(row.id); const labelId = `enhanced-table-checkbox-${index}`; return ( <TableRow hover onClick={(event) => handleClick(event, row.id)} role="checkbox" aria-checked={isItemSelected} tabIndex={-1} key={row.id} selected={isItemSelected} > <TableCell padding="checkbox"> <Checkbox checked={isItemSelected} inputProps={{ 'aria-labelledby': labelId }} /> </TableCell> {columns.map((column) => { const value = row[column.id]; return ( <TableCell key={column.id} align={column.align}> {column.format && typeof value === 'number' ? column.format(value) : value} </TableCell> ); })} </TableRow> ); })} {/* 保留原有空行占位逻辑 */} {emptyRows > 0 && ( <TableRow style={{ height: 53 * emptyRows }}> <TableCell colSpan={columns.length + 1} /> </TableRow> )} </TableBody>
可选优化
- 若需精确匹配,将
includes替换为===即可 - 给输入框加防抖(比如用
useDebounce钩子),减少频繁过滤的性能消耗 - 针对日期、数字类型列,可单独编写专属过滤逻辑(如数字范围匹配)
内容的提问来源于stack exchange,提问作者Akinalp
相关产品推荐
相关产品推荐

