尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Refine 中 Ant Design useTable 完整指南:从基础用法到排序、过滤、搜索与分页

Refine 中 Ant Design useTable 完整指南:从基础用法到排序、过滤、搜索与分页 Refine 中 Ant Design useTable 完整指南从基础用法到排序、过滤、搜索与分页【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineuseTable是 Refine 在 Ant Design 集成层提供的数据表格 Hook它把 Refine 的数据获取、分页、排序、过滤能力与 Ant DesignTable组件无缝对接开箱即用地完成后台管理页中最常见的列表页。本文以文档 useTable 指南 为骨架结合refinedev/antd的源码实现完整讲解其基础用法、分页、排序、过滤、搜索、初始化状态、Realtime 支持以及全部属性和返回值读完即可在项目中直接落地一个功能完整的表格页面。一、useTable 是什么Ant Design 表格与 Refine 数据层的桥梁useTable返回与 Ant DesignTable组件兼容的tableProps排序、过滤、分页等特性全部开箱即用。其底层使用 Refine core 的useList负责数据拉取因此天然继承了 Refine 的 data provider、缓存、错误重试等能力。更关键的是refinedev/antd的useTable是从refinedev/core包的useTable扩展而来的所有 core 层特性如syncWithLocation、liveMode、overtimeOptions等都可以直接使用antd 版本在 core 基础上额外增加了onSearch与searchFormProps两个搜索相关能力。从源码 packages/antd/src/hooks/table/useTable/useTable.ts 可以看到antd 层的useTable接收onSearch、pagination、filters、sorters、syncWithLocation、resource、queryOptions、liveMode、meta、dataProviderName等参数内部调用 core 的useTableCore获取查询状态随后把这些状态映射成 Ant Design 表格所需的TableProps。import { useTable } from refinedev/antd; import { Table } from antd; interface IPost { id: number; title: string; content: string; status: published | draft | rejected; } const PostList: React.FC () { const { tableProps } useTableIPost(); return ( Table {...tableProps} rowKeyid Table.Column dataIndexid titleID / Table.Column dataIndextitle titleTitle / Table.Column dataIndexcontent titleContent / Table.Column dataIndexstatus titleStatus render{(value: string) TagField value{value} /} / /Table ); };这段代码展示的是最基础的用法useTable默认从 URL 推断resource例如路由/posts对应posts资源然后直接展开tableProps到Table上即可。TagField是refinedev/antd提供的字段组件用于把状态值渲染成 Tag 标签。完整的可运行示例可以参考仓库中的 examples/table-antd-use-table该示例使用refinedev/simple-restdata provider 连接api.fake-rest.refine.dev并在Refine中声明了posts资源。二、Pagination 分页开箱即用并支持 URL 同步分页功能由tableProps.pagination提供useTable会为Table组件生成分页链接而不是依赖 React state并且会覆盖Table默认的pagination.itemRender值。从源码 packages/antd/src/hooks/table/useTable/useTable.ts 可以看出useTable内部构造了一个 Ant Design 分页配置对象使用createLinkForSyncWithLocation生成每一页的链接PaginationLink在 paginationLink.tsx 中实现通过useLink渲染为框架对应的链接组件并自动适配响应式——小屏时simple: true且分页位置改为bottomCenter桌面端为bottomRight总数为data?.total。如果你开启了syncWithLocation分页状态连同排序、过滤会自动同步到 URL 查询参数中用户刷新、收藏、分享链接时表格状态得以保留。对分页的自定义只需要把tableProps.pagination展开后覆盖需要的字段即可const { tableProps } useTableIPost(); Table {...tableProps} rowKeyid pagination{{ ...tableProps.pagination, position: [bottomCenter], size: small, }} {/* --- */} /Table;分页模式的三种取值通过pagination.mode可以控制分页的处理位置默认值为servermode行为off关闭分页一次性获取全部记录client客户端分页先拉取全部记录再在浏览器端切页server服务端分页根据currentPage与pageSize发起请求默认useTable({ pagination: { mode: client, }, });pagination.currentPage设置初始页码默认1pagination.pageSize设置每页条数默认10。三、Sorting 排序把 sorter 状态转成 API 参数要给某列开启排序只需要给对应的Table.Column加上sorter属性。开启syncWithLocation后排序状态同样会同步到 URL。在排序请求发出时Column组件的key属性会作为 API 请求中的字段名使用如果列没有key则回退使用dataIndex。当你希望排序字段名与dataIndex不同例如展示嵌套字段、排序键特殊时可以用key显式指定。多列排序时sorter属性必须传入multiple值来声明该列在排序中的优先级。在源码 packages/antd/src/definitions/table/index.ts 的mapAntdSorterToCrudSorting中可以看到Ant Design 的sorter事件结果会按column.sorter.multiple升序排序后映射为 Refine 的CrudSorting数组类型的field嵌套字段会被join(.)成点分路径最终字段名优先取columnKey。这一点在测试 packages/antd/src/definitions/table/index.spec.ts 中有明确验证两个排序列按multiple的优先级重排field数组被转换成version.title这样的点分字段。useTableIPost({ sorters: { initial: [ { field: title, order: asc, }, ], }, });四、Filtering 过滤基于列的 filterDropdown列过滤使用Table.Column的filterDropdown属性实现。做法是把过滤表单放进refinedev/antd提供的FilterDropdown组件中并把filterDropdown回调收到的属性透传给该组件Table.Column dataIndexstatus titleStatus filterDropdown{(props) ( FilterDropdown {...props} Radio.Group Radio valuepublishedPublished/Radio Radio valuedraftDraft/Radio Radio valuerejectedRejected/Radio /Radio.Group /FilterDropdown )} /过滤状态同样支持syncWithLocation同步到 URL。useTable内部通过mapAntdFilterToCrudFilter源码见 packages/antd/src/definitions/table/index.ts把 Ant Design 的过滤值映射为 Refine 的CrudFilters数组值映射为in操作符标量值映射为eq操作符并尽量沿用已有过滤器或initial过滤器的操作符。测试用例 index.spec.ts 覆盖了数组、标量、0值等映射场景。五、初始排序与初始过滤别忘了同步到 Table 列使用initial初始化排序/过滤时必须同时给Table.Column设置getDefaultSortOrder或defaultFilteredValue否则 Hook 的状态与表格显示可能不同步const { tableProps, sorters, filters } useTable({ sorters: { initial: [ { field: title, order: asc, }, ], }, filters: { initial: [ { field: status, operator: eq, value: published, }, ], }, }); Table.Column dataIndextitle titleTitle defaultSortOrder{getDefaultSortOrder(title, sorters)} / Table.Column dataIndexstatus titleStatus defaultFilteredValue{getDefaultFilter(status, filters)} filterDropdown{(props) ( FilterDropdown {...props} Radio.Group Radio valuepublishedPublished/Radio Radio valuedraftDraft/Radio Radio valuerejectedRejected/Radio /Radio.Group /FilterDropdown )} /getDefaultSortOrder与getDefaultFilter都从refinedev/antd导出。其中getDefaultSortOrder会先把 Refine 的asc | desc转换成 Ant Design 的ascend | descend源码见 packages/antd/src/definitions/table/index.ts测试 index.spec.ts 验证了该转换。getDefaultFilter用于按字段和操作符取出过滤值便于在渲染时回填 UIimport { getDefaultFilter, useTable } from refinedev/antd; const MyComponent () { const { filters } useTable({ filters: { initial: [ { field: name, operator: contains, value: John Doe, }, ], }, }); const nameFilterValue getDefaultFilter(name, filters, contains); console.log(nameFilterValue); // John Doe };六、Search 搜索onSearch searchFormProps 定制过滤表单useTable提供了onSearch与searchFormProps两个属性用于构建自定义搜索表单。onSearch在表单提交时被调用接收表单值并返回CrudFilters或PromiseCrudFilters同时会把当前页重置为第1页searchFormProps则直接传给 Ant Design 的Form组件。import { HttpError } from refinedev/core; import { List, useTable, SaveButton } from refinedev/antd; import { Table, Form, Input } from antd; interface IPost { id: number; title: string; } interface ISearch { title: string; } const PostList: React.FC () { const { searchFormProps, tableProps } useTableIPost, HttpError, ISearch({ onSearch: (values) { return [ { field: title, operator: contains, value: values.title, }, ]; }, }); return ( List Form {...searchFormProps} layoutinline Form.Item nametitle Input placeholderSearch by title / /Form.Item SaveButton onClick{searchFormProps.form?.submit} / /Form Table {...tableProps} rowKeyid Table.Column dataIndexid titleID / Table.Column titleTitle dataIndextitle / /Table /List ); };源码中searchFormProps由 Ant Design 的Form.useForm与sunflower-antd的useFormSF组合生成并覆写了onFinish——提交时调用onSearch得到过滤条件后交给setFilters见 packages/antd/src/hooks/table/useTable/useTable.ts。也可以使用searchFormProps.form.submit手动提交表单。七、Realtime 实时更新当配置了LiveProvider后useTable挂载时会调用liveProvider的subscribe方法传入channel、resource等参数订阅实时事件。相关属性包括liveModeauto收到实时事件自动更新数据或manual不自动更新。onLiveEvent订阅到新事件时的回调函数。liveParams透传给liveProvider.subscribe的参数。useTable({ liveMode: auto, onLiveEvent: (event) { console.log(event); }, });八、常用属性详解resource 与 identifier默认情况下resource从当前路由推断。也可以显式指定useTable({ resource: categories, });当存在多个同名资源时可以传identifier作为资源匹配键data provider 方法仍会使用Refine/中声明的name执行请求。dataProviderName存在多个 data provider 时用dataProviderName指定本次查询使用的 provideruseTable({ dataProviderName: second-data-provider, });sorters.initial 与 sorters.permanentsorters.initial设置排序的初始值它不是永久的——用户改变排序后即被清除若希望排序永久生效、不可被用户修改使用sorters.permanentuseTable({ sorters: { permanent: [ { field: name, order: asc, }, ], }, });sorters.modeserver默认或off。off时不把 sorters 发送给服务器可配合 Ant Design 的列sorter做纯客户端排序。filters.initial 与 filters.permanent与 sorters 同理initial是非永久初始过滤permanent永久生效useTable({ filters: { permanent: [ { field: name, operator: contains, value: Foo, }, ], }, });filters.defaultBehavior过滤行为默认mergemerge新过滤器与已有过滤器合并同列的旧过滤器被替换不同列则追加。replace用新过滤器整体替换已有过滤器。也可以在调用setFilters时通过第二个参数临时覆盖useTable({ filters: { defaultBehavior: replace, }, });filters.modeserver默认或off。off时过滤在客户端完成useTable完全兼容 Ant DesignTable原生的列过滤特性const ListPage () { const { tableProps } useTable({ filters: { mode: off, }, }); return ( Table {...tableProps} rowKeyid Table.Column dataIndexstatus titleStatus filters{[ { text: Published, value: published }, { text: Draft, value: draft }, { text: Rejected, value: rejected }, ]} onFilter{(value, record) record.status value} / /Table ); };同理sorters.mode: off关闭服务端排序改用 Ant Design 列的sorter{(a, b) a.id - b.id}做客户端排序。syncWithLocation开启后useTable的排序、过滤、分页状态会自动编码进 URL 查询参数URL 变化时表格状态也会自动恢复。默认false可以在 hook 级别或Refine的options中开启示例 examples/table-antd-use-table/src/App.tsx 就是在Refine options里全局开启的useTable({ syncWithLocation: true, });queryOptionsuseTable使用useList拉取数据可以把 TanStack Query 的queryOptions透传下去useTable({ queryOptions: { retry: 3, }, });metameta用于向 data provider 方法传递额外信息典型用途是定制请求行为或生成 GraphQL 查询。例如给getList传递自定义请求头useTable({ meta: { headers: { x-meta-data: true }, }, }); const myDataProvider { getList: async ({ resource, pagination, sorters, filters, meta }) { const headers meta?.headers ?? {}; const url ${apiUrl}/${resource}; const { data } await httpClient.get(${url}, { headers }); return { data }; }, };successNotification 与 errorNotification配合NotificationProvider使用数据拉取成功/失败时自定义通知内容useTable({ successNotification: (data, values, resource) ({ message: ${data.title} Successfully fetched., description: Success with no errors, type: success, }), errorNotification: (data, values, resource) ({ message: Something went wrong when getting ${data.id}, description: Error, type: error, }), });overtimeOptions用于展示请求超时加载提示。interval为毫秒间隔onInterval为每个间隔触发的回调。Hook 返回overtime对象elapsedTime是已流逝毫秒数请求完成后变为undefinedconst { overtime } useTable({ overtimeOptions: { interval: 1000, onInterval(elapsedInterval) { console.log(elapsedInterval); }, }, }); // overtime.elapsedTime: undefined, 1000, 2000, 3000, 4000, ... { overtime.elapsedTime 4000 divthis takes a bit longer than expected/div; }九、返回值详解useTable的返回值在 packages/antd/src/hooks/table/useTable/useTable.ts 中组装主要包含返回值说明tableProps直接传给 Ant DesignTable的属性dataSource、loading、onChange、pagination、scrollsearchFormPropsAnt DesignForm属性onFinish触发onSearch也可用searchFormProps.form.submit手动提交tableQueryuseList的返回值即 TanStack Query 的useQuery结果data、total、isLoading等sorters/setSorters当前排序状态及设置函数filters/setFilters当前过滤状态及设置函数setFilters支持(filters, behavior?: merge \| replace)或函数式更新currentPage/setCurrentPage当前页码状态分页关闭时为undefinedpageSize/setPageSize当前每页条数状态分页关闭时为undefinedpageCount总页数分页关闭时为undefinedcreateLinkForSyncWithLocation生成syncWithLocation可访问链接的函数overtime超时加载状态elapsedTime为毫秒数几个值得注意的细节tableProps.onChange是用户与表格交互过滤、排序、分页时的回调。useTable正是通过这个函数来管理排序、过滤与分页状态的如果覆盖它就需要手动处理这些操作。源码中onChange会把 Ant Design 的过滤器映射成CrudFilters、把排序器映射成CrudSorting并在分页开启时同步currentPage与pageSize见 useTable.ts。tableProps.scroll默认为{ x: true }即表格默认允许横向滚动。tableProps.loading在liveMode auto时取isLoading否则取!isFetched确保实时模式下数据更新时不闪加载态。tableProps.dataSource中的数据来自useList拉取的结果。十、FAQ关系数据、客户端过滤与排序关系数据怎么处理可以用useMany拉取关系数据配合useSelect生成分类过滤下拉框在表格中展示关联字段并支持按关联过滤。客户端过滤与排序两种能力本质上就是把filters.mode/sorters.mode设为off放弃服务端处理完全交给 Ant DesignTable原生的filters/onFilter与sorter属性实现代码示例见上文filters.mode与sorters.mode小节。这也是文档明确推荐的零请求式表格方案。十一、类型参数与更多资源useTable支持四个泛型参数源码注释见 useTable.ts类型参数说明默认值TQueryFnData查询函数返回的数据类型需继承BaseRecordBaseRecordTError自定义错误类型需继承HttpErrorHttpErrorTSearchVariables搜索表单参数类型{}TDataselect后的结果类型需继承BaseRecordTQueryFnData仓库中refinedev/antd的useTable相关源码与测试可继续深入阅读核心实现packages/antd/src/hooks/table/useTable/useTable.ts分页链接组件packages/antd/src/hooks/table/useTable/paginationLink.tsx排序/过滤映射工具packages/antd/src/definitions/table/index.ts映射函数测试packages/antd/src/definitions/table/index.spec.ts完整示例examples/table-antd-use-table掌握了useTable你就掌握了 Refine 中列表页的核心形态把它与List、Table.Column、FilterDropdown、TagField等组件组合再加上 data provider 的支撑一个支持分页、排序、过滤、搜索和实时更新的后台数据列表即可快速落地。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表