让Agent封装一个Table组件--

0 阅读6分钟

目标

  • 实现一个公共表格组件:在 components 目录下封装 CommonTable,API 高度对齐 antd Table 的核心字段(columnsdataSourcerowKeypaginationrowSelectiononChange 等),支持基础渲染、分页、排序、筛选、选择。
  • 实现筛选条件设置组件:独立封装 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>,继承/模仿 antd ColumnType<T> 的核心字段:keydataIndextitlewidthalignrendersorterfiltersonFilterellipsis 等,去掉暂时不支持的复杂属性。
    • 支持 filterMultipledefaultSortOrdersortDirections 等简单排序/筛选配置。
  • 表格组件 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 的 Table onChange,方便上层复用现有逻辑。
    • 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 用来区分和 localStorage key。

UI 与交互设计(对齐原型图)

  • 整体布局

    • 顶部:左侧为“筛选条件区域”(FilterBuilder)、右上角为搜索框和操作按钮(如“新增”、“导出”等预留 slot)。
    • 中间:列设置入口(如“列设置”按钮 + 下拉列表,多选勾选列)。
    • 下半部分:表格主体 + 底部分页条,布局与原型图一致。
  • 样式实现要点

    • 使用 Tailwind 组合实现卡片背景、阴影、圆角,表头分割线、hover 高亮、选中行高亮等。
    • 利用 tailwindcss-animate/tw-animate-css 为筛选条件的出现/删除、列设置面板展开/收起增加简单动画(例如 animate-fade-inanimate-slide-down 之类)。
    • 针对“列头筛选”使用表头右侧小图标(可用 SVG icon 或任意 icon 库),点击弹出一个小面板展示 filters 选项,多选后点击“确定/重置”。

行为逻辑设计

  • 客户端/服务端分页

    • pagination.serverSide !== true:在 CommonTable 内部根据 currentpageSizedataSource 进行 slice,并计算当前页数据;用户点击分页器时更新内部状态,并触发 onChange(pagination, filters, sorter, extra),同时透出 pagination.onChange
    • pagination.serverSide === true:仅透传页码和页大小到 onChangepagination.onChange,不在内部对 dataSource 进行裁剪,由外部负责请求和传入当前页数据。
  • 排序

    • 支持单列排序:在列头点击排序按钮时更新内部 sorter 状态,根据列配置中提供的 sorter 函数或默认逻辑对当前展示数据排序。
    • onChange 中带上 { field, order } 信息,与 antd 一致。
  • 列筛选与表头筛选

    • 使用列配置中的 filters 字段,点击表头筛选图标弹出选项,下拉多选后应用过滤逻辑:优先使用列上的 onFilter 函数,否则默认按 record[dataIndex] 包含关系过滤。
    • 过滤状态同步到 filters 对象,以 dataIndex 为 key。
  • 行选择(含跨页)

    • 由内部维护 selectedRowKeySet,分页变化时不清空,保证跨页仍能记住已经勾选的行。
    • rowSelection.selectedRowKeys 提供时,切换为受控模式,内部仅通过回调通知外部。

筛选条件设置组件实现细节

  • 字段元数据输入

    • 上层通过 fields: FilterFieldMeta[] 传入可筛选的字段列表,包含 fieldlabeltype、可用 operators 等。
  • 条件编辑交互

    • 支持“添加条件”下拉:列出可用字段,选择后在下方列表新增一行条件编辑区域(字段名 + 操作符 + 对应类型的输入控件)。
    • 不同类型对应不同控件:text 输入框、number 数字输入、select 下拉单选/多选、date/dateRange 用日期选择器(如使用已有库或简单输入占位)、boolean 切换开关等。
    • 修改条件时暂存在内部 state,仅当点击“应用/保存”按钮或某种明确的“确认”动作时才触发 onChange,符合“当条件完成变更时才触发”的要求。
  • 本地缓存与回显

    • 使用 localStorage key:filter_builder_${id} 存储整个条件数组 JSON 字符串。
    • 提供“保存当前条件”为一个命名方案(或直接覆盖当前 id 下缓存),下次在“添加条件”或专门的“历史条件”下拉中可点击回显。

列设置组件实现细节

  • 列设置按钮(例如“列设置”icon + 文字)点击后,弹出一个面板:

    • 列出当前所有可展示列,使用 checkbox 控制是否显示;顺序可暂不支持拖拽,如需扩展可用 react-beautiful-dnd 等。
    • 变更列显示后,更新 visibleColumns 列表并影响 CommonTable 的实际渲染列集合。
    • 通过 columnSettingsProps 允许外部控制默认隐藏列和持久化策略(可选)。

与 antd Table 的差异与兼容策略

  • 尽量兼容

    • columnsdataSourcerowKeypaginationrowSelectiononChange 的字段命名和基本结构与 antd 保持一致,让已有 antd 表格使用方迁移成本低。
  • 有意简化

    • 初版不实现 antd Table 的所有功能(如分组表头、固定列、可伸缩列宽、可树形展示等),在类型和文档中明确标注“暂不支持的字段将被忽略”。

示例与使用方式

  • src/examples/TableDemo.tsx 中添加一个演示页面:

    • 演示基本列表 + 顶部筛选 + 表头筛选 + 客户端分页 + 多选 + 列设置。
    • 示例中给出典型 columns 配置、FilterBuilder 配置、onChange 数据流示例,方便你在真实业务中直接 Copy 改。

后续可扩展方向(非必须)

  • 支持多列排序(组合排序顺序、在 sorter 中传入数组)。
  • 支持行展开/详情(在 columns 外再增加 expandable 配置)。
  • 支持虚拟滚动(对接 react-window/react-virtualized,用于大数据列表)。
  • 将筛选条件与 URL query 同步,方便分享和刷新后保留状态。