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

资讯详情

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

Refine Mantine ExportButton 组件详解:数据导出按钮的定制与 useExport 实战

Refine Mantine ExportButton 组件详解:数据导出按钮的定制与 useExport 实战 Refine Mantine ExportButton 组件详解数据导出按钮的定制与 useExport 实战【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineExportButton是 Refine 在 Mantine 适配层中提供的开箱即用导出按钮它本质上是 MantineButton为主体结合packages/mantine与packages/core中的源码与测试讲解该组件的用法、全部属性、底层实现原理以及如何与useExport组合成完整的导出实战方案。:::simple 本文速览掌握ExportButton的基本用法、hideText等核心属性通过源码理解按钮的“纯展示”定位与默认文案/图标的来源结合useExport的完整参数表实现分页拉取、字段映射、自定义文件名与 CSV 下载了解 Swizzle 定制入口与跨 UI 库共用的测试基座。:::ExportButton 是什么ExportButton是一个 MantineButton带有默认的导出图标和默认文本 “Export”。它在数据层面只有展示价值presentational真正的导出逻辑由核心包提供的useExportHook 承担两者通过onClick与loading串联起来。这一“纯展示”定位在源码中有明确体现。Mantine 版实现 中组件只做了三件事通过useExportButton()获取本地化后的默认文案label根据hideText决定渲染ActionIcon仅图标还是Button图标 文本统一挂载data-testid与className供测试与样式覆盖使用。import { ActionIcon, Button } from mantine/core; import { IconFileExport } from tabler/icons-react; export const ExportButton: React.FCExportButtonProps ({ hideText false, children, loading false, svgIconProps, ...rest }) { const { label } useExportButton(); // ... return hideText ? ( ActionIcon loading{loading} aria-label{label} ... IconFileExport size{18} {...svgIconProps} / /ActionIcon ) : ( Button variantdefault loading{loading} leftIcon{IconFileExport size{18} /} ... {children ?? label} /Button ); };默认文案label由核心包的按钮 Hook 体系提供。packages/core/src/hooks/button/index.tsx 中useExportButton与useSaveButton、useImportButton一样统一收敛到useActionableButton({ type: export })由 i18n 上下文给出 “Export” 之类的翻译因此当你的应用配置了多语言时按钮文字会自动随语言包切换。基本用法给列表页加上导出能力导出按钮最常见的应用场景是列表页List头部。它本身不包含任何导出逻辑需要配合refinedev/core的useExportHook 使用import { useExport } from refinedev/core; import { List, ExportButton } from refinedev/mantine; import { Table, Pagination } from mantine/core; import { useTable } from refinedev/react-table; import { ColumnDef, flexRender } from tanstack/react-table; const PostList: React.FC () { const columns React.useMemoColumnDefIPost[]( () [ { id: id, header: ID, accessorKey: id }, { id: title, header: Title, accessorKey: title }, ], [], ); const { reactTable: { getHeaderGroups, getRowModel }, refineCore: { setCurrentPage, pageCount, currentPage }, } useTable({ columns }); const { triggerExport, isLoading: exportLoading } useExportIPost({ mapData: (item) ({ id: item.id, post_title: item.title, }), pageSize: 10, maxItemCount: 50, }); return ( List headerButtons{ ExportButton loading{exportLoading} onClick{triggerExport} / } Table thead {getHeaderGroups().map((headerGroup) ( tr key{headerGroup.id} {headerGroup.headers.map((header) ( th key{header.id} {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} /th ))} /tr ))} /thead tbody {getRowModel().rows.map((row) ( tr key{row.id} {row.getVisibleCells().map((cell) ( td key{cell.id} {flexRender(cell.column.columnDef.cell, cell.getContext())} /td ))} /tr ))} /tbody /Table br / Pagination positionright total{pageCount} page{currentPage} onChange{setCurrentPage} / /List ); }; interface IPost { id: number; title: string; }要点说明触发链路点击按钮 → 调用triggerExport→useExport内部通过 data provider 的getList分批拉取数据 → 用 papaparse 序列化为 CSV → 触发浏览器下载加载态loading{exportLoading}让按钮在导出过程中显示 loading 状态并防止重复点击位置通过List组件的headerButtons插槽放入列表页头部工具栏这是 Refine 推荐的放法也可以放到任意你想放置的位置。PropertiesExportButton 的全部属性hideTexthideText用于控制是否显示按钮文字。当为true时只显示导出图标import { ExportButton } from refinedev/mantine; const MyExportComponent () { return ExportButton hideText /; };从源码可见hideText模式下组件渲染的是 Mantine 的ActionIcon图标按钮并自动带上aria-label{label}保证无障碍可访问性非隐藏模式下渲染Button文字优先使用children未传children时才回退到默认的label。其余常用属性ExportButton的属性类型定义为RefineExportButtonPropsButtonProps, CommonButtonProps见 packages/mantine/src/components/buttons/types.ts即除下面列出的自定义属性外MantineButton的全部属性variant、size、color、disabled、onClick等均可直接透传属性类型默认值说明hideTextbooleanfalse为true时仅显示图标隐藏 “Export” 文本childrenReactNode—自定义按钮文字优先级高于默认文案loadingbooleanfalse导出进行中显示加载态源码中透传给Button/ActionIconsvgIconPropsOmitIconProps, ref—自定义IconFileExport图标的尺寸、颜色等属性hiddenboolean—由CommonButtonProps提供的通用隐藏开关onClick事件回调—点击处理通常绑定triggerExport此外Mantine 版按钮内部使用mapButtonVariantToActionIconVariant将Button的 variant 映射为ActionIcon的 variant因此在hideText与普通模式之间切换时视觉风格可以保持一致。底层原理useExport 如何工作虽然本文主角是ExportButton但要写出可用的导出功能理解 useExport 实现 是必要的。核心流程如下解析资源通过useResourceParams拿到当前资源名若存在多个 data provider用pickDataProvider选择正确的 provider。分批拉取以pageSize默认 20为一批循环调用getListpagination.mode固定为server以启用服务端分页直到满足以下任一条件停止已拉取数据量达到maxItemCountrawData.length total所有数据已取完。字段映射对每条记录执行mapData用于重命名/裁剪导出字段例如把item.title输出为post_title。序列化与下载使用 papaparse 的unparse生成 CSV默认quotes: true、header: true并通过downloadInBrowser触发浏览器下载文件名中的空格会被替换为下划线并支持 BOM 前缀默认开启便于 Excel 正确识别 UTF-8。useExport的完整可配置项如下参数类型默认值说明resourcestring从路由读取要导出的资源名mapDataMapDataFn(item) item对每条记录执行的字段映射函数sortersCrudSort[]—导出数据的排序规则filtersCrudFilter[]—导出数据的过滤规则maxItemCountnumber—导出的最大记录数上限pageSizenumber20每批拉取的条数即getList的页大小unparseConfigUnparseConfig{ quotes: true, header: true }papaparse 序列化配置metaMetaQuery—传给 data provider 的元数据dataProviderNamestring—多 data provider 时指定使用的 provideronError(error) void—导出失败回调downloadbooleantrue是否在浏览器触发下载filenamestring资源名-当前时间自定义导出文件名不含扩展名useTextFilebooleanfalse为true时导出.txt文本文件useBombooleantrue是否在文件头写入 BOMtitlestringMy Generated Report导出文件的标题文本showTitlebooleanfalse是否在文件首行输出标题返回值为{ isLoading, triggerExport }isLoading驱动按钮的 loading 态triggerExport是异步函数调用后返回生成的 CSV 字符串或undefined。一个更贴近实战的自定义示例const { triggerExport, isLoading } useExportIPost({ resource: posts, filename: posts_report, pageSize: 50, useTextFile: false, title: Posts Report, showTitle: true, mapData: (item) ({ id: item.id, title: item.title }), onError: (error) console.error(Export failed:, error), }); return ExportButton loading{isLoading} onClick{triggerExport} /;Swizzle一键定制 ExportButton如果你需要深度定制例如更换图标、调整默认样式、增加业务逻辑Refine 官方推荐使用 Swizzle 机制运行 Refine CLI 的 swizzle 命令后组件源码会被复制进你的项目src目录此后你可以直接修改这份副本而不影响框架升级。npm run refine swizzle refinedev/mantine ExportButtonSwizzle 能力对应的文档元数据为swizzle: true见 文档 frontmatter。定制后的按钮依然可以依赖useExportButton获取本地化文案从而在保持团队 i18n 一致性的前提下自由改版。测试基座跨 UI 库共用的导出按钮行为Refine 的 UI 组件测试是跨适配层共用的。Mantine 版测试 直接委托给refinedev/ui-tests中的buttonExportTests它验证了四条核心行为见 packages/ui-tests/src/tests/buttons/export.tsx无 props 时默认渲染出 “Export” 文本挂载了正确的data-testidRefineButtonTestIds.ExportButton传入children时优先渲染自定义文本设置hideText后不再出现 “Export” 文本。这意味着你在 Ant Design、Material UI、Chakra UI 等任意适配层中使用对应导出按钮时这些基础行为都是被同一套测试保障的可以放心迁移。小结ExportButton是纯展示组件图标 “Export” 文案默认文案来自 i18n支持children覆盖与hideText图标模式导出逻辑全部交给useExport它负责分页拉取、字段映射、papaparse 序列化与浏览器下载并返回isLoading/triggerExport与按钮对接合理使用参数pageSize控制批大小、maxItemCount防止超大导出、mapData裁剪字段、filename/useTextFile/useBom定制输出文件需要深度定制时优先使用 Refine CLI 的 Swizzle 将组件复制到项目内修改保持升级兼容的同时实现自定义样式与逻辑。掌握了这套“按钮 Hook”的组合你就能在 Refine Mantine 应用中快速为任意资源列表添加一键导出的完整能力。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表