ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Refine v5 Material UI Create 组件完全指南:构建与深度定制创建页面

Refine v5 Material UI Create 组件完全指南:构建与深度定制创建页面 Refine v5 Material UI Create 组件完全指南构建与深度定制创建页面【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本指南以 Refine v5 的 Material UI 集成包refinedev/mui为核心深入讲解基础视图组件Create的定位、用法与全部属性。你将学会用Create快速搭建创建页面骨架并通过title、saveButtonProps、goBack、isLoading、breadcrumb、headerButtons、footerButtons等属性完成从标题、返回按钮到页头页脚按钮的精细定制同时结合仓库源码理解其底层实现原理与测试断言为打造规范、可维护的后台管理界面提供可直接落地的方案。Create是什么一个纯粹的布局组件Create是 Refine 在 Material UI 集成中提供的基础视图组件之一。它只负责搭建创建页面的布局骨架本身不包含任何业务逻辑而是额外提供两类能力页面标题与动作按钮默认包含返回按钮、页脚保存按钮与面包屑。在仓库源码 packages/mui/src/components/crud/create/index.tsx 中组件顶部注释明确写道Createprovides us a layout to display the page. It does not contain any logic but adds extra functionalities like action buttons and giving titles to the page.这句话界定了Create的职责边界逻辑交给 Hook如useForm布局交给Create。实际提交数据、校验、请求都由useForm、data provider 等完成Create只负责把页面装帧起来。从实现上看Create由一组 Material UI 卡片类组件组合而成Card外层容器即 wrapperCardHeader头部返回按钮 标题 头部按钮CardContent内容区渲染表单等 childrenCardActions页脚保存按钮等动作区这一组合对应了CreateProps类型中wrapperProps/headerProps/contentProps/footerButtonProps等属性的设计来源详见 packages/mui/src/components/crud/types.ts。快速上手构建一个完整的创建页面下面是一个完整的Create页面示例它结合useForm来自refinedev/react-hook-form实现表单注册与提交结合useAutocomplete来自refinedev/mui实现关联资源的单选下拉并用Breadcrumb提供面包屑导航import React from react; import { Create, useAutocomplete, Breadcrumb } from refinedev/mui; import { Autocomplete, Box, TextField } from mui/material; import { useForm } from refinedev/react-hook-form; import { Controller } from react-hook-form; import { useState } from react; const SampleCreate () { const { saveButtonProps, refineCore: { formLoading }, register, control, formState: { errors }, } useForm(); const { autocompleteProps: categoryAutocompleteProps } useAutocomplete({ resource: categories, }); return ( Create isLoading{formLoading} saveButtonProps{saveButtonProps} Box componentform sx{{ display: flex, flexDirection: column }} autoCompleteoff TextField {...register(title, { required: This field is required, })} error{!!(errors as any)?.title} helperText{(errors as any)?.title?.message} marginnormal fullWidth slotProps{{ InputLabelProps: { shrink: true }, }} typetext labelTitle nametitle / TextField {...register(content, { required: This field is required, })} error{!!(errors as any)?.content} helperText{(errors as any)?.content?.message} marginnormal fullWidth slotProps{{ InputLabelProps: { shrink: true }, }} multiline labelContent namecontent / Controller control{control} namecategory rules{{ required: This field is required }} // eslint-disable-next-line defaultValue{null as any} render{({ field }) ( Autocomplete {...categoryAutocompleteProps} {...field} onChange{(_, value) { field.onChange(value); }} getOptionLabel{(item) { return ( categoryAutocompleteProps?.options?.find( (p) p?.id?.toString() item?.id?.toString(), )?.title ?? ); }} isOptionEqualToValue{(option, value) value undefined || option?.id?.toString() (value?.id ?? value)?.toString() } renderInput{(params) ( TextField {...params} labelCategory marginnormal variantoutlined error{!!(errors as any)?.category?.id} helperText{(errors as any)?.category?.id?.message} required / )} / )} / /Box Breadcrumb / /Create ); };在这个示例中有四个关键点值得注意isLoading{formLoading}把useForm返回的提交加载状态透传给Create提交期间组件会显示加载遮罩并禁用保存按钮详见下文isLoading一节。saveButtonProps{saveButtonProps}把表单 Hook 生成的保存按钮属性含onClick提交逻辑、disabled状态注入Create页脚的默认SaveButton会自动拾取它们。ControlleruseAutocomplete用于把第三方受控组件MUIAutocomplete接入 react-hook-form同时由useAutocomplete负责按resource: categories拉取选项数据。Breadcrumb作为 children 放入Create配合路由信息渲染页面层级导航。路由层面你需要为资源注册create路由并挂载该页面例如resources{[ { name: posts, list: /posts, create: /posts/create, }, { name: categories, list: /categories, create: /categories/create, }, ]}Route pathcreate element{SampleCreate /} /属性详解15 个属性的用法与语义Create的属性定义来自refinedev/ui-types的RefineCrudCreateProps基类型packages/ui-types/src/types/crud.tsxMaterial UI 版本在其上映射了具体的 MUI 组件属性CardProps、CardHeaderProps、CardContentProps、CardActionsProps、BoxProps等。以下逐一说明。title自定义页面标题通过title属性替换默认标题。默认标题由资源标签 Create拼接而来例如Create Post详见下方源码视角小节。import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create titleCustom Title spanRest of your page here/span /Create ); };resource指定表单使用的资源resource属性决定表单使用哪个资源。默认情况下Create会从当前路由中推断资源当你需要在一个路由下为其他资源渲染创建页时可以用它显式指定import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create resourcecategories spanRest of your page here/span /Create ); };从源码看该属性会被传入useResourceParams({ resource: resourceFromProps })从而影响默认标题、面包屑与数据交互所绑定的资源packages/mui/src/components/crud/create/index.tsx。类型注释中也标注了其默认行为Reads :resource from the URL。saveButtonProps定制保存按钮页脚的默认SaveButton通过saveButtonProps定制通常直接把useForm返回的saveButtonProps透传进来也可以覆写其 MUI 按钮样式import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create saveButtonProps{{ size: large, variant: contained, color: secondary, }} spanRest of your page here/span /Create ); };从源码看saveButtonProps会与加载状态合并isLoading为true时自动附加disabled: true再透传给默认的SaveButtonpackages/mui/src/components/crud/create/index.tsx。关于SaveButton的完整能力如hideText、图标槽位、加载态可参考 SaveButton 文档 及其实现 packages/mui/src/components/buttons/save/index.tsx。goBack控制返回按钮goBack属性决定页头是否显示返回按钮。默认渲染一个ArrowBack图标按钮调用useBack进行路由回退设置为false即可隐藏import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create goBack{false} spanRest of your page here/span /Create ); };你也可以传入任意ReactNode如自定义图标或文字替换默认的返回按钮。类型定义中goBack?: React.ReactNode与default值为ArrowLeft /见 packages/ui-types/src/types/crud.tsx。isLoading展示加载状态isLoading用于在数据/提交过程中展示加载反馈。置为true时组件会渲染一个覆盖整个 Card 的半透明遮罩 CircularProgress加载圈同时禁用保存按钮import { Create } from refinedev/mui; import { useState } from react; const PostCreate: React.FC () { const [loading, setLoading] useState(true); return ( Create isLoading{loading} spanRest of your page here/span /Create ); };源码中的遮罩实现值得留意它使用position: absoluteinset: 0铺满容器背景色通过alpha(theme.palette.background.paper, 0.4)计算并显式注释这是为了支持自定义主题与暗色模式说明其背景色会跟随主题而非写死packages/mui/src/components/crud/create/index.tsx。isLoading的默认值为false见CreateProps解构处。breadcrumb定制或禁用面包屑breadcrumb属性用于自定义面包屑。默认使用refinedev/mui包中的Breadcrumb组件传入false可完全禁用传入自定义 ReactNode 可替换import { Create, Breadcrumb } from refinedev/mui; const PostCreate: React.FC () { return ( Create breadcrumb{ div style{{ padding: 3px 6px, border: 2px dashed #888, }} Breadcrumb / /div } spanRest of your page here/span /Create ); };源码中只要传入breadcrumb就会渲染你提供的节点否则渲染默认Breadcrumb /packages/mui/src/components/crud/create/index.tsx。Breadcrumb组件的更多用法见 Breadcrumb 文档。wrapperProps / headerProps / contentProps / footerProps分层样式定制Create的布局分为 wrapperCard 容器、headerCardHeader 头部、contentCardContent 内容区与 footerCardActions 页脚四层分别用四个属性透传底层 MUI 组件的 props最常用的是sx样式import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create wrapperProps{{ sx: { backgroundColor: lightsteelblue }, }} headerProps{{ sx: { backgroundColor: lightsteelblue }, }} contentProps{{ sx: { backgroundColor: lightsteelblue }, }} footerProps{{ sx: { backgroundColor: lightsteelblue }, }} spanRest of your page here/span /Create ); };wrapperProps透传给 MUICard其sx会与组件内置的position: relative默认样式浅合并源码使用...wrapperProps?.sx展开覆盖packages/mui/src/components/crud/create/index.tsx。headerProps透传给CardHeader内置样式会保证标题区flexWrap换行并让操作区垂直居中。contentProps透传给CardContent包裹表单等 children。footerProps透传给CardActions内置样式为justifyContent: flex-end按钮靠右与padding: 16px。这四个属性的类型分别对应 MUI 的CardProps、CardHeaderProps、CardContentProps、CardActionsProps见 packages/mui/src/components/crud/types.ts。headerButtons / headerButtonProps定制页头按钮区页头按钮区默认不渲染任何按钮与List默认有CreateButton、Show默认有EditButton/DeleteButton不同因此常见做法是用headerButtons渲染一个回到列表按钮。它接受false隐藏或一个返回ReactNode的函数函数参数中包含defaultButtons此处默认为nullimport { Create } from refinedev/mui; import { Button } from mui/material; const PostCreate: React.FC () { return ( Create headerButtons{({ defaultButtons }) ( {defaultButtons} Button variantcontained onClick{() { console.log(Custom button clicked); }} Custom Button /Button / )} spanRest of your page here/span /Create ); };headerButtonProps则用于给页头按钮的外层容器MUIBox默认display: flex、gap: 16px追加属性例如给列表按钮注入样式import { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create headerButtonProps{{ listButtonProps: { size: large, variant: contained, color: secondary, }, }} spanRest of your page here/span /Create ); };注意headerButtons与headerButtonProps的语义边界——前者决定渲染什么按钮后者决定按钮外层容器的 props。footerButtons / footerButtonProps定制页脚按钮区页脚默认渲染一个SaveButton。footerButtons同样接受false或渲染函数函数参数中带有defaultButtons默认保存按钮与saveButtonProps方便你在保留默认保存按钮的同时追加自定义按钮import { Create } from refinedev/mui; import { Button } from mui/material; const PostCreate: React.FC () { return ( Create footerButtons{({ defaultButtons }) ( {defaultButtons} Button variantcontained onClick{() { console.log(Custom button clicked); }} Custom Button /Button / )} spanRest of your page here/span /Create ); };footerButtonProps用于给页脚容器MUICardActions追加属性或直接覆写保存按钮自身的 propsimport { Create } from refinedev/mui; const PostCreate: React.FC () { return ( Create footerButtonProps{{ saveButtonProps: { size: large, variant: contained, color: secondary, }, }} spanRest of your page here/span /Create ); };从源码看footerButtons为函数时defaultButtons即SaveButton {...saveButtonProps} /packages/mui/src/components/crud/create/index.tsx。源码视角Create的默认渲染逻辑阅读 packages/mui/src/components/crud/create/index.tsx 的完整实现可以梳理出Create的默认行为链条1. 资源与标题解析。组件通过useResourceParams({ resource: resourceFromProps })拿到当前resource、action与identifier通过useUserFriendlyName把资源名转为人类可读的单数形式标题默认值用useTranslate查{identifier}.titles.create的翻译键未命中时回退为Create ${getUserFriendlyName(...)}这就是Create Post这类默认标题的来源。2. 返回按钮的显隐判断。默认返回按钮只有在存在可回退的历史时才绑定点击逻辑源码中onClick仅在action ! list或action未定义时绑定back来自useBack否则按钮存在但不做跳转。3. 保存按钮与加载态联动。当isLoading为true时saveButtonProps会被追加disabled: true同时遮罩层zIndex取theme.zIndex.drawer 1确保加载圈浮于页面内容之上。4. 类型底座。CreateProps RefineCrudCreatePropsSaveButtonProps, BoxProps, CardActionsProps, CardProps, CardHeaderProps, CardContentProps, {}即把 ui-types 的通用 CRUD 类型映射到 MUI 的具体组件类型上packages/mui/src/components/crud/types.ts这也解释了为何各集成包的Create属性结构一致、仅底层组件不同。测试验证通用 CRUD Create 断言仓库中的 UI 测试为所有 UI 集成包提供了统一的Create行为断言packages/ui-tests/src/tests/crud/create.tsx可将其视为官方对组件行为的契约渲染 childrenCreateSomething/Create必须把内容渲染出来默认保存按钮不传任何 props 时页脚应出现data-testid为RefineButtonTestIds.SaveButton的按钮footerButtons 注入传入自定义按钮时能被渲染测试使用buttonOptional Button/button默认标题路由为/posts/create时页面应显示Create Posttitle{false} 隐藏标题传入title{false}后默认标题不再出现meta.label 优先资源配置meta: { label: test label }时标题按 label 渲染而非资源名。这些用例直接对应了前文介绍的title、footerButtons、saveButtonProps等属性语义也是你在自定义或 swizzle 该组件后回归验证的参考清单。延伸阅读保存按钮的完整定制能力SaveButton 文档面包屑组件用法Breadcrumb 文档一个完整的 Material UI 表单示例应用含PostCreate页面挂载方式examples/form-material-ui-use-form/src/App.tsxCreate在 MUI 包中的实现与类型定义packages/mui/src/components/crud/create/index.tsx、packages/mui/src/components/crud/types.ts通用 CRUD 类型底座packages/ui-types/src/types/crud.tsx通用测试断言packages/ui-tests/src/tests/crud/create.tsx如果你希望进一步定制Create例如改变默认遮罩样式、调整页脚布局可以通过 Refine CLI 的swizzle命令把该组件弹出到项目内直接修改相关 CLI 源码位于 packages/cli。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表