- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
本文以 rsuite 组件库中的 Card 组件为核心,讲解如何将 Card 与其 Header / Body / Footer 子组件组合成一个结构清晰的「创建项目」表单容器,并通过form属性实现表单与外部提交按钮的跨区域联动。读完本文,你将掌握 Card 组件在表单场景中的标准写法、各子组件的职责划分、width/size/shaded等布局属性的实际效果,以及 Form + SelectPicker 等组件在 Card 内的组合用法。
场景概述:为什么用 Card 承载表单
Card 是 rsuite 中用于结构化展示数据的容器组件,可以包含图片、文本、按钮等多种子组件(见 docs/pages/components/card/en-US/index.md)。在表单场景中,Card 天然具备"分组 + 层次"的优势:
- 视觉分区:Header 放标题与说明、Body 放表单控件、Footer 放操作按钮,三块职责清晰;
- 尺寸约束:通过
width直接限定卡片宽度,避免表单控件无限拉伸; - 操作聚合:Footer 中的提交/取消按钮与 Body 中的表单在视觉上同属一个卡片,交互连贯。
在 rsuite 的文档示例中,「Within Form」一节正是以"创建项目(Create project)"表单为例,演示了这种组合模式(见 within-form.md)。
完整代码示例与运行方式
以下为「创建项目」表单的完整实现,来自 docs/pages/components/card/fragments/within-form.md:
import { Card, Heading, Text, Form, Button, SelectPicker } from 'rsuite'; const App = () => { return ( <Card width={400} shaded size="lg"> <Card.Header> <Heading level={4}>Create project</Heading> <Text muted>Fill in the form below to create a new project</Text> </Card.Header> <Card.Body> <Form fluid id="project-form" onSubmit={formValue => console.log(formValue)}> <Form.Group> <Form.ControlLabel>Name</Form.ControlLabel> <Form.Control name="name" placeholder="Name of project" /> </Form.Group> <Form.Group> <Form.ControlLabel>Platform</Form.ControlLabel> <Form.Control block name="platform" searchable={false} accepter={SelectPicker} placeholder="Select platform" data={[ { label: 'Web', value: 'web' }, { label: 'Mobile', value: 'mobile' }, { label: 'Desktop', value: 'desktop' } ]} /> </Form.Group> </Form> </Card.Body> <Card.Footer> <Button appearance="primary" type="submit" form="project-form"> Create </Button> <Button appearance="subtle">Cancel</Button> </Card.Footer> </Card> ); }; ReactDOM.render(<App />, document.getElementById('root'));该示例可直接在 rsuite 文档站点的 Card 组件页("Within Form" 小节)中运行预览。在本地项目中,你只需通过import { Card, Form, Button, SelectPicker } from 'rsuite'引入对应组件,即可复刻同样的效果。
剖析 Card 的三段式结构:Header / Body / Footer
在 rsuite 中,Card是一个复合组件,通过静态属性挂载了三个子组件(见 src/Card/Card.tsx):
const Subcomponents = { Header: CardHeader, Body: CardBody, Footer: CardFooter };因此你既可以写Card.Header,也可以从rsuite中单独导入CardHeader、CardBody、CardFooter使用(导出关系见 src/Card/index.tsx)。三个子组件均由createComponent创建为<div>元素(见 src/Card/CardHeader.tsx、src/Card/CardBody.tsx、src/Card/CardFooter.tsx),职责划分如下:
| 子组件 | 语义职责 | 示例中的内容 |
|---|---|---|
Card.Header | 卡片头部,通常放标题与简介 | Heading level={4}(标题)+Text muted(灰色说明文字) |
Card.Body | 卡片主体,承载主要数据或表单控件 | Form(表单控件组) |
Card.Footer | 卡片底部,放操作入口 | Button(Create / Cancel) |
从样式实现看,三块区域有着不同的内边距规则(见 src/Card/styles/index.scss):
-header:padding: var(--rs-card-padding) var(--rs-card-padding) 0 var(--rs-card-padding)(上左右有内边距,底部为 0);-body:四边均为var(--rs-card-padding);-footer:display: flex; gap: 8px;,按钮之间自动保持 8px 间距,底部内边距留白。
这种"Header 紧贴 Body、Footer 独立成行"的间距设计,正是示例中标题、表单、按钮三层视觉层次感的来源。
关键布局属性:width、size 与 shaded
示例卡片对外部形态设置了三个属性,均声明在 src/Card/Card.tsx 的CardProps中:
| 属性 | 类型 | 默认值 | 作用 |
|---|---|---|---|
width | number \| string | — | 卡片宽度,示例中设为400(px) |
size | 'sm' \| 'md' \| 'lg' | — | 卡片尺寸,示例中设为'lg' |
shaded | boolean \| 'hover' | — | 是否显示阴影,示例中为true |
bordered | boolean | true | 是否显示边框 |
实现细节:
- width 通过 CSS 变量注入:
Card内部将width值写入--rs-card-width变量(cssVar('width', width, getCssValue)),样式表中的.rs-card默认width: var(--rs-card-width),默认回退为100%。这意味着不传width时卡片占满父容器,传入数字(如 400)时则按像素固定宽度。 - size 控制内边距:样式表对
data-size属性做了分级处理——sm为calc(var(--rs-spacing) * 2),md为calc(var(--rs-spacing) * 4),lg为calc(var(--rs-spacing) * 6)。示例选用size="lg",可获得最大的内边距,适合承载表单这种信息密度较高的内容。 - shaded 控制阴影:
data-shaded='true'时启用box-shadow: var(--rs-card-shadow);若设为'hover',则仅在鼠标悬停时显示阴影并带有cursor: pointer。示例用shaded(布尔值)让卡片常驻阴影,在页面中更醒目。
表单与按钮的跨区域联动:form 属性的巧妙用法
本示例最值得学习的技巧在于:提交按钮并不在<Form>内部,而是位于Card.Footer中,两者通过 HTML 原生form属性完成关联:
<Form fluid id="project-form" onSubmit={formValue => console.log(formValue)}> ... </Form> <Card.Footer> <Button appearance="primary" type="submit" form="project-form"> Create </Button> </Card.Footer>- 给
<Form>设置id="project-form"; - 给 Footer 中的提交按钮设置
type="submit"与form="project-form"。
浏览器会将form属性指向的<form>元素视为该按钮的宿主表单,因此点击 Footer 中的Create按钮即可触发表单提交,并触发<Form>的onSubmit回调((formValue, event) => void,见 src/Form/Form.tsx)。示例中onSubmit将收集到的表单值直接console.log输出,实际项目中可替换为接口调用或状态更新。
这种写法打破了"表单控件必须与按钮同处一个父级"的直觉,让布局可以自由跨区域组织,是 Card 承载复杂交互时的重要模式。
表单细节:fluid、accepter 与 SelectPicker
示例中的表单控件有两个值得注意的配置:
Form 的fluid属性
<Form fluid id="project-form" onSubmit={formValue => console.log(formValue)}>fluid让表单内的输入控件占满表单容器宽度(仅在垂直布局下有效,见 src/Form/Form.tsx 中fluid?: boolean的注释)。在width={400}的固定宽度卡片中,配合fluid可保证输入框完整撑开卡片主体,避免左右出现参差空隙。
accepter 替换控件与 searchable
<Form.Control block name="platform" searchable={false} accepter={SelectPicker} placeholder="Select platform" data={[ { label: 'Web', value: 'web' }, { label: 'Mobile', value: 'mobile' }, { label: 'Desktop', value: 'desktop' } ]} />Form.Control默认渲染为文本框,通过accepter={SelectPicker}可以将它替换为选择器组件;data提供选项数组(label为展示文本、value为提交值),block让选择器占满宽度,searchable={false}关闭搜索功能。提交后platform字段的值会是'web'、'mobile'或'desktop'三者之一。
Name 输入框
<Form.Control name="name" placeholder="Name of project" />未指定accepter时渲染为普通文本框,用户输入的项目名通过name="name"映射到表单值对象中。
相关扩展:卡片尺寸与阴影的更多用法
如果你希望在表单卡片之外进一步掌握 Card 的视觉控制,仓库文档还提供了多个关联示例(见 docs/pages/components/card/en-US/index.md 的 Examples 小节):
- Shadow / Hover Shadow:分别对应
shaded的常驻阴影与shaded="hover"悬停阴影用法(shadow.md、hover-shadow.md); - Sizes:
size取sm/md/lg三种尺寸的直观对比(size.md); - Horizontal:通过
direction="row"实现横向布局(horizontal.md); - Card Group:如需同时展示多个卡片,可使用
CardGroup组件,它支持columns(列数)与spacing(间距,默认 16)两个属性。
小结
本文围绕 rsuite 的 "Within Form" 示例,完整拆解了用 Card 构建「创建项目」表单的实现方案:利用Card.Header/Card.Body/Card.Footer三段式结构组织标题、表单与操作按钮;通过width、size、shaded控制卡片外观;借助 HTML 原生form属性让 Footer 中的按钮跨区域触发表单提交;再配合Form的fluid、accepter={SelectPicker}等配置完成控件定制。这套组合既保持了 Card 的视觉统一性,又兼顾了表单交互的完整性,是 rsuite 中"容器卡片 + 表单"场景的推荐实践。
- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
相关推荐
Optuna 如何在单机多进程上并行调参并共享 JournalStorage
Optuna 如何在单机多进程上并行调参并共享 JournalStorage 在单机上跑 Optuna 调参时,如果只想利用多个 CPU 核心而不想额外部署 M
前端UI组件MNN 如何开启 CoreML 后端在 iOS 上使用 NPU 加速?
MNN 如何开启 CoreML 后端在 iOS 上使用 NPU 加速? 在 iOS 应用里使用 MNN 做推理时,如果你希望借助苹果设备的 NPU(ANE)硬件
前端UI组件coss Card 组件实战指南:用 Card/CardHeader/CardPanel/CardFooter 构建结构化内容区块
coss Card 组件实战指南:用 Card/CardHeader/CardPanel/CardFooter 构建结构化内容区块 导读 coss Card 是
企业应用后端前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考