☰
rsuite Card 组件实战:用 Card 构建「创建项目」表单的完整方案
2026/9/26 2:07:42 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】rsuite

🧱 A suite of React components .

项目地址:https://gitcode.com/gh_mirrors/rs/rsuite
点击查看免费下载

本文以 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中:

属性类型默认值作用
widthnumber \| string—卡片宽度,示例中设为400(px)
size'sm' \| 'md' \| 'lg'—卡片尺寸,示例中设为'lg'
shadedboolean \| 'hover'—是否显示阴影,示例中为true
borderedbooleantrue是否显示边框

实现细节:

  • 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 .

项目地址:https://gitcode.com/gh_mirrors/rs/rsuite
点击查看免费下载
上一篇:Terracognita 快速入门指南:10分钟掌握云资源反向转换技巧
下一篇:QGroundControl故障排查与优化:10个常见问题解决方案大全

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询