ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Refine Ant Design Inferencer 组件实战:用 @refinedev/inferencer 自动生成 List / Show / Create / Edit 页面

Refine Ant Design Inferencer 组件实战:用 @refinedev/inferencer 自动生成 List / Show / Create / Edit 页面 Refine Ant Design Inferencer 组件实战用 refinedev/inferencer 自动生成 List / Show / Create / Edit 页面【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本文围绕 Refine 生态中的refinedev/inferencer包深入讲解其 Ant Design 集成组件AntdInferencer及其拆分的AntdListInferencer、AntdShowInferencer、AntdEditInferencer、AntdCreateInferencer。你将学会如何在路由中零配置地使用它们、如何在自定义组件中显式传入resource/action/id并理解字段类型推断、关联资源探测与代码生成这三条底层流水线最终把生成的可复制代码迁移到正式页面中。概览Inferencer 能做什么refinedev/inferencer是一个基于资源数据结构自动生成视图代码的实验性包。它通过Refine/组件提供的dataProvider拉取资源数据据此推断每个字段的类型再按 UI 框架生成对应的组件与源码。当前仓库中它按 UI 包划分导出作用域refinedev/inferencer/antd即对应refinedev/antdAnt Design 集成的作用域此外还有 Material UI、Mantine、Chakra UI 与 Headless 版本见 Inferencer 集成文档。针对 Ant Designrefinedev/inferencer/antd共导出五个组件组件生成的视图底层使用的 Ant Design / Refine 能力AntdListInferencer列表页ListTableuseTableAntdShowInferencer详情页Show 各字段组件 useShowAntdCreateInferencer创建页CreateuseFormAntdEditInferencer编辑页EdituseFormAntdInferencer以上四者的聚合入口根据当前路由的action自动分发从源码看AntdInferencer的聚合逻辑很直接它从refinedev/core的useParsed()中读取当前路由解析出的action与id然后按action分别渲染ShowInferencer、CreateInferencer、EditInferencer默认即list渲染ListInferencer实现代码见 antd/index.tsx。这也解释了为什么在路由中只放一个AntdInferencer /就能覆盖四种页面。安装在项目已安装refinedev/antd、antd与refinedev/core中安装npm install refinedev/inferencer # 或 pnpm add refinedev/inferencer该包当前标记为experimental官方建议仅用于开发环境辅助生成代码不应用于生产环境详见 packages/inferencer 文档。快速使用两种接入方式Inferencer 组件支持两种用法路由推断与显式传参。官方文档给出了完整示例这里逐条拆解。方式一放在 resources 对应的路由中零 props当你配置了routerProvider时AntdInferencer会自动从当前路由推断resource、action和id因此可以不传任何 propsimport routerProvider from refinedev/react-router; import { BrowserRouter } from react-router; // highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const App () { return ( BrowserRouter Refine routerProvider{routerProvider} resources{[ { name: samples, list: /samples, }, ]} Routes {/* highlight-next-line */} Route path/samples element{AntdInferencer /} / /Routes /Refine /BrowserRouter ); };要点resources中声明的list路径必须与Route path/samples一致若资源同时声明了show、create、edit路径只需在对应路由挂载同一个AntdInferencer /它会根据路由段自动切换到对应的视图/samples→ list/samples/show/123→ show/samples/create→ create/samples/edit/123→ edit。方式二在自定义组件中显式传 props当你不依赖路由、想把 Inferencer 嵌入现有页面时可以用resource、action、id三个 props 精确指定要生成的视图// highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const SampleList () { return ( // highlight-next-line AntdInferencer resourcesamples actionlist / ); }; const SampleShow () { return ( // highlight-next-line AntdInferencer resourcesamples actionshow id1 / ); }; const SampleCreate () { return ( // highlight-next-line AntdInferencer resourcesamples actioncreate / ); }; const SampleEdit () { return ( // highlight-next-line AntdInferencer resourcesamples actionedit id1 / ); };注意show与edit需要指定id否则无法发起getOne请求list与create不需要idcreate视图基于列表接口返回的第一条记录来推断表单字段。完整 props 定义name/resource/action/id/fieldTransformer/meta/hideCodeViewerInProduction可查看 types/index.ts。更多细节参见 Inferencer 集成文档。四种视图各自生成什么下面四个可运行示例均使用refinedev/simple-rest提供的假数据 APIhttps://api.fake-rest.refine.dev与ThemedLayout布局读者可直接复制到自己的 Refine 应用中对照学习。List列表页AntdListInferencer根据列表接口的响应推断列结构使用refinedev/antd的List、Table与useTablesetInitialRoutes([/samples]); import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/antd; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { ConfigProvider } from antd; import { BrowserRouter, Routes, Route, Outlet } from react-router; // highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( BrowserRouter ConfigProvider theme{RefineThemes.Blue} Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, list: /samples, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } {/* highlight-next-line */} Route path/samples element{AntdInferencer /} / /Route /Routes /Refine /ConfigProvider /BrowserRouter ); };生成的列表页会按字段类型挑选 Ant Design 字段组件日期列用DateField、邮箱列用EmailField、图片列用ImageField限制maxWidth: 100px、布尔列用BooleanField、富文本列用MarkdownField截取前 80 字符、URL 列用UrlField、多值列用TagField平铺展示。列定义通过dataIndex{[key, accessor]}支持嵌套对象取值。资源若配置了canEdit/canShow/canDelete或edit/show路由与resourceMeta还会追加一列 Actions内置EditButton、ShowButton、DeleteButton均为hideText sizesmall样式。上述逻辑的完整实现见 antd/list.tsx。Show详情页AntdShowInferencer根据单条记录的结构生成详情视图使用refinedev/antd的Show与字段组件数据由refinedev/core的useShow提供setInitialRoutes([/samples/show/123]); import { Refine } from refinedev/core; import { RefineThemes, ThemedLayout } from refinedev/antd; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { ConfigProvider } from antd; import { BrowserRouter, Routes, Route, Outlet } from react-router; // highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( BrowserRouter ConfigProvider theme{RefineThemes.Blue} Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, show: /samples/show/:id, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } {/* highlight-next-line */} Route path/samples/show/:id element{AntdInferencer /} / /Route /Routes /Refine /ConfigProvider /BrowserRouter ); };详情页会用 antd 的Typography体系逐字段渲染标题、段落、文本等日期、图片、邮箱、布尔、URL、富文本同样映射到对应字段组件。Create创建页AntdCreateInferencer根据列表接口返回的第一条记录推断表单字段使用refinedev/antd的Create与useFormsetInitialRoutes([/samples/create]); import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/antd; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { ConfigProvider } from antd; import { BrowserRouter, Routes, Route, Outlet } from react-router; // highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( BrowserRouter ConfigProvider theme{RefineThemes.Blue} Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, create: /samples/create, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } {/* highlight-nextline */} Route path/samples/create element{AntdInferencer /} / /Route /Routes /Refine /ConfigProvider /BrowserRouter ); };Edit编辑页AntdEditInferencer根据单条记录推断表单字段含默认值回填使用refinedev/antd的Edit与useFormsetInitialRoutes([/samples/edit/123]); import { Refine } from refinedev/core; import { ThemedLayout, RefineThemes } from refinedev/antd; import routerProvider from refinedev/react-router; import dataProvider from refinedev/simple-rest; import { ConfigProvider } from antd; import { BrowserRouter, Routes, Route, Outlet } from react-router; // highlight-next-line import { AntdInferencer } from refinedev/inferencer/antd; const API_URL https://api.fake-rest.refine.dev; const App: React.FC () { return ( BrowserRouter ConfigProvider theme{RefineThemes.Blue} Refine routerProvider{routerProvider} dataProvider{dataProvider(API_URL)} resources{[ { name: samples, edit: /samples/edit/:id, }, ]} Routes Route element{ ThemedLayout Outlet / /ThemedLayout } {/* highlight-next-line */} Route path/samples/edit/:id element{AntdInferencer /} / /Route /Routes /Refine /ConfigProvider /BrowserRouter ); };表单视图会根据字段类型选择对应的 antd 表单控件文本输入、数字输入、日期选择、开关、选择器等关联字段自动转换为Select并配合useSelect加载选项。底层原理数据如何获取与字段如何推断数据获取策略refinedev/inferencer通过Refine/的dataProvider取数策略与视图类型相关edit / show以resourceid发起getOne请求list / create发起getList请求并从返回列表中取一条记录作为推断依据create需要表单字段故也用列表数据。这些请求在你的应用内真实发生因此需要应用已正确配置dataProvider。从源码结构看取数与推断由 use-infer-fetch 与 use-relation-fetch 两个内部 hook 协作完成最终在 create-inferencer/index.tsx 中驱动整个流水线。字段类型推断推断器是一组函数集合每个函数检查字段是否符合某种类型并返回推断结果同时附带priority优先级字段当同一字段能匹配多种类型时例如created_at既是字符串又像日期优先级高的类型胜出。默认推断器在 field-inferencers/index.ts 中注册覆盖以下类型type Types | relation | array | object | date | email | image | url | richtext | text | number | boolean | unknown | custom_${string};其中custom_${string}由各 UI 包的 Inferencer 内部使用例如 Ant Design 对某些字段有专属控件表示目前用户还不能向组件传入自定义类型与推断函数。对多值属性会判定为array并对其元素值递归执行同样的推断以确定元素类型object类型同理递归处理。两者在返回值中都可以带accessor字段用于在生成视图与代码时定位取值路径。对于object类型Inferencer 会尝试挑选一个代表性键来展示该属性例如{ label: string; id: string }这样的category字段会选择label作为展示键这类可展示的object字段在返回结果中fieldable为true。可作展示键的字段名PresentationalKeys包括name、label、title、count、content、username、nickname、login、firstName、lastName、url。关联关系如何判定在字段被判定为relation之前会先检查若干不会触发 API 调用的条件属性名以id或ids结尾支持 camelCase、PascalCase、snake_case、kebab-case、UPPER_CASE、lower_case且允许带数组括号属性是仅含单个id键的对象属性是仅含单个id键的对象数组或由 UUID 兼容字符串/数字组成的数组属性是字符串或数字且属性名与某个已知资源单数或复数匹配。满足其一即标记为relation随后按以下顺序确定关联资源优先在resources数组中按属性名单数或复数匹配资源匹配失败时向defaultdataProvider 分别发送单数与复数去掉id后缀资源名的两次请求请求成功HTTP 200则确定为关联资源并使用该资源及其dataProvider按属性值发请求全部失败则撤销relation标记退回普通字段若为object类型则尝试寻找最佳展示键。若你的dataProvider/resources组织方式让 Inferencer 无法自动识别关联可以改用fieldTransformer手动修正推断结果见下文。组件渲染与代码生成字段确定后createInferencer调用各 UI 包、各 action 专属的renderer函数它返回一段组件源码字符串既用于在页面上实时渲染通过支持 TypeScript 的react-livefork 执行也用于在代码查看器中展示用户可一键复制到自己的工程。组件名由当前资源与 action 组合而成优先取resource.meta.label否则取resource.name例如资源categories的 list 视图组件名为CategoryList。整条渲染管线与 props 说明见 create-inferencer/index.tsx 与 types/index.ts。高级用法为 GraphQL 后端传 meta 值Refine 通过数据 hook 的meta属性支持 GraphQL 后端。Inferencer 的metaprop 采用嵌套结构允许按资源 × 方法分别定义 meta 值因为 Inferencer 可能发现关联资源并额外发起getMany/getOne等请求AntdListInferencer meta{{ [resourceNameOrIdentifier: string]: { [methodName: default | getList | getMany | getOne | update]: Recordstring, unknown, } }} /default是全部方法的兜底 meta 值某资源某方法未单独配置时回退到default。示例AntdListInferencer meta{{ posts: { getList: { fields: [id, title, content, category_id, created_at], }, }, categories: { default: { fields: [id, title], }, }, }} /用 fieldTransformer 修改推断结果若想定制输出——例如为object字段设置自定义accessor、改变字段type、或调整relation的关联资源——可使用fieldTransformerprop。它是一个接收字段、返回修改后字段的函数返回undefined | false | null时该字段会从预览与代码中一并移除AntdListInferencer fieldTransformer{(field) { // 隐藏 createdAt 字段 if (field.key createdAt) return undefined; // 其余字段原样保留 return field; }} /该函数在每个字段完成内置推断与转换之后、进入渲染器之前被调用实现见 create-inferencer/index.tsx。隐藏代码查看器与开发警告生产环境下可用hideCodeViewerInProduction隐藏代码查看器与提示信息块开发环境下始终可见。但请注意Inferencer 组件本身不应用于生产环境它定位为开发期脚手架工具帮助快速生成可复制的页面代码。完整示例与源码导航仓库内置了完整可运行的 inferencer-antd 示例包含 Ant Design 版 List / Show / Create / Edit 全部视图是最佳上手参照。Ant Design 专属的四个 renderer 分别位于 inferencers/antd/list.tsx、show.tsx、create.tsx、edit.tsx并有配套快照测试__tests__/__snapshots__锁定生成代码的形态。字段推断器的单元测试如 date.test.ts、relation.test.ts可用于理解各类字段的判定边界。小结refinedev/inferencer把为资源编写 CRUD 页面这件事压缩成了三个步骤挂路由或传 props、让组件读取数据并推断字段、把生成代码复制进正式组件。对 Ant Design 用户来说AntdInferencer一个组件即可覆盖四种页面而fieldTransformer与meta两个 prop 又提供了对推断结果和后端差异的修正能力。在实际项目中推荐把它当作开发期脚手架使用先用 Inferencer 快速产出原型再基于生成的代码按业务需求定制从而兼顾开发速度与代码可控性。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表