目标
- 实现一个公共表格组件:在
components目录下封装CommonTable,API 高度对齐 antdTable的核心字段(columns、dataSource、rowKey、pagination、rowSelection、onChange等),支持基础渲染、分页、排序、筛选、选择。 - 实现筛选条件设置组件:独立封装
FilterBuilder(或类似命名),支持根据字段类型渲染不同输入控件、添加/删除条件、保存到localStorage并回显、用onChange通知上层。 - 视觉尽量靠近文档原型图:用 TailwindCSS 和
tailwindcss-animate/tw-animate-css还原顶部筛选区、列设置区、表格区整体布局和交互细节。
目录和文件规划
-
基础结构(可根据你现有项目轻微调整路径):
src/components/table/CommonTable.tsx:主表格组件,对外暴露与 antd 相似的 API。src/components/table/FilterBuilder.tsx:顶部“筛选条件设置组件”,支持条件组合与本地缓存。src/components/table/ColumnSettings.tsx:列显示/隐藏配置弹出层或下拉面板。src/components/table/types.ts:公共 TS 类型定义,抽象 antd Table 兼容层和筛选条件类型。src/components/table/Pagination.tsx(可选):如需自定义分页器样式则独立封装,否则直接用简单的按钮 + 下拉组合在CommonTable内实现。
类型与 API 设计
-
列定义类型(参考 antd):
- 在
types.ts中定义CommonColumn<T>,继承/模仿 antdColumnType<T>的核心字段:key、dataIndex、title、width、align、render、sorter、filters、onFilter、ellipsis等,去掉暂时不支持的复杂属性。 - 支持
filterMultiple、defaultSortOrder、sortDirections等简单排序/筛选配置。
- 在
-
表格组件 props:
columns: CommonColumn<T>[],dataSource: T[],rowKey: string | ((record: T) => React.Key)。pagination?: { current: number; pageSize: number; total?: number; onChange?: (page, pageSize) => void; serverSide?: boolean; },通过serverSide标记由外部拉取数据还是内部本地分页。rowSelection?: { type?: 'checkbox' | 'radio'; selectedRowKeys?: React.Key[]; onChange?: (selectedRowKeys, selectedRows) => void; preserveSelectedRowKeys?: boolean; },支持跨页选择(内部用Set管理)。loading?: boolean; bordered?: boolean; size?: 'small' | 'middle' | 'large';。onChange?: (pagination, filters, sorter, extra) => void,事件签名紧贴 antd 的 TableonChange,方便上层复用现有逻辑。filterBuilderProps?: FilterBuilderProps; columnSettingsProps?: ColumnSettingsProps;,用于打开顶部筛选和列设置区。
-
筛选条件类型:
FilterFieldType = 'text' | 'number' | 'select' | 'date' | 'dateRange' | 'boolean'。FilterCondition = { field: string; label: string; type: FilterFieldType; operator: string; value: any; }。FilterBuilderProps = { id: string; fields: FilterFieldMeta[]; value?: FilterCondition[]; onChange?: (conditions: FilterCondition[]) => void; },id用来区分和localStoragekey。
UI 与交互设计(对齐原型图)
-
整体布局:
- 顶部:左侧为“筛选条件区域”(
FilterBuilder)、右上角为搜索框和操作按钮(如“新增”、“导出”等预留 slot)。 - 中间:列设置入口(如“列设置”按钮 + 下拉列表,多选勾选列)。
- 下半部分:表格主体 + 底部分页条,布局与原型图一致。
- 顶部:左侧为“筛选条件区域”(
-
样式实现要点:
- 使用 Tailwind 组合实现卡片背景、阴影、圆角,表头分割线、hover 高亮、选中行高亮等。
- 利用
tailwindcss-animate/tw-animate-css为筛选条件的出现/删除、列设置面板展开/收起增加简单动画(例如animate-fade-in、animate-slide-down之类)。 - 针对“列头筛选”使用表头右侧小图标(可用 SVG icon 或任意 icon 库),点击弹出一个小面板展示
filters选项,多选后点击“确定/重置”。
行为逻辑设计
-
客户端/服务端分页:
- 当
pagination.serverSide !== true:在CommonTable内部根据current、pageSize对dataSource进行slice,并计算当前页数据;用户点击分页器时更新内部状态,并触发onChange(pagination, filters, sorter, extra),同时透出pagination.onChange。 - 当
pagination.serverSide === true:仅透传页码和页大小到onChange与pagination.onChange,不在内部对dataSource进行裁剪,由外部负责请求和传入当前页数据。
- 当
-
排序:
- 支持单列排序:在列头点击排序按钮时更新内部
sorter状态,根据列配置中提供的sorter函数或默认逻辑对当前展示数据排序。 onChange中带上{ field, order }信息,与 antd 一致。
- 支持单列排序:在列头点击排序按钮时更新内部
-
列筛选与表头筛选:
- 使用列配置中的
filters字段,点击表头筛选图标弹出选项,下拉多选后应用过滤逻辑:优先使用列上的onFilter函数,否则默认按record[dataIndex]包含关系过滤。 - 过滤状态同步到
filters对象,以dataIndex为 key。
- 使用列配置中的
-
行选择(含跨页) :
- 由内部维护
selectedRowKeySet,分页变化时不清空,保证跨页仍能记住已经勾选的行。 - 当
rowSelection.selectedRowKeys提供时,切换为受控模式,内部仅通过回调通知外部。
- 由内部维护
筛选条件设置组件实现细节
-
字段元数据输入:
- 上层通过
fields: FilterFieldMeta[]传入可筛选的字段列表,包含field、label、type、可用operators等。
- 上层通过
-
条件编辑交互:
- 支持“添加条件”下拉:列出可用字段,选择后在下方列表新增一行条件编辑区域(字段名 + 操作符 + 对应类型的输入控件)。
- 不同类型对应不同控件:
text输入框、number数字输入、select下拉单选/多选、date/dateRange用日期选择器(如使用已有库或简单输入占位)、boolean切换开关等。 - 修改条件时暂存在内部 state,仅当点击“应用/保存”按钮或某种明确的“确认”动作时才触发
onChange,符合“当条件完成变更时才触发”的要求。
-
本地缓存与回显:
- 使用
localStoragekey:filter_builder_${id}存储整个条件数组 JSON 字符串。 - 提供“保存当前条件”为一个命名方案(或直接覆盖当前 id 下缓存),下次在“添加条件”或专门的“历史条件”下拉中可点击回显。
- 使用
列设置组件实现细节
-
列设置按钮(例如“列设置”icon + 文字)点击后,弹出一个面板:
- 列出当前所有可展示列,使用 checkbox 控制是否显示;顺序可暂不支持拖拽,如需扩展可用
react-beautiful-dnd等。 - 变更列显示后,更新
visibleColumns列表并影响CommonTable的实际渲染列集合。 - 通过
columnSettingsProps允许外部控制默认隐藏列和持久化策略(可选)。
- 列出当前所有可展示列,使用 checkbox 控制是否显示;顺序可暂不支持拖拽,如需扩展可用
与 antd Table 的差异与兼容策略
-
尽量兼容:
columns、dataSource、rowKey、pagination、rowSelection、onChange的字段命名和基本结构与 antd 保持一致,让已有 antd 表格使用方迁移成本低。
-
有意简化:
- 初版不实现 antd Table 的所有功能(如分组表头、固定列、可伸缩列宽、可树形展示等),在类型和文档中明确标注“暂不支持的字段将被忽略”。
示例与使用方式
-
在
src/examples/TableDemo.tsx中添加一个演示页面:- 演示基本列表 + 顶部筛选 + 表头筛选 + 客户端分页 + 多选 + 列设置。
- 示例中给出典型
columns配置、FilterBuilder配置、onChange数据流示例,方便你在真实业务中直接 Copy 改。
后续可扩展方向(非必须)
- 支持多列排序(组合排序顺序、在
sorter中传入数组)。 - 支持行展开/详情(在
columns外再增加expandable配置)。 - 支持虚拟滚动(对接
react-window/react-virtualized,用于大数据列表)。 - 将筛选条件与 URL query 同步,方便分享和刷新后保留状态。