资讯详情

资讯详情

antd Card.Grid 卡片宫格内容区隔模式:从 Demo 到源码级实现解析

antd Card.Grid 卡片宫格内容区隔模式从 Demo 到源码级实现解析【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design卡片Card是 ant-designAnt Design React中最常用的容器组件之一而Card.Grid提供了一种经典的宫格化内容区隔模式在不引入额外 Grid/Col 布局的前提下让卡片内容区域自动等分成多个网格单元适用于菜单入口、数据看板、功能模块导航等场景。本文以 grid-card Demo 为核心结合 Grid.tsx、Card.tsx 与 样式实现 源码完整讲解Card.Grid的用法、属性、默认值与底层实现原理帮助你在项目中正确、灵活地使用这一模式。一、什么是 Card.Grid一种常见的卡片内容区隔模式Card.Grid是 ant-design 为Card组件提供的静态子组件复合组件模式官方对其的定位是一种常见的卡片内容区隔模式Grid style card content。它的核心思想是在卡片内部以**网格单元grid cell**的形式组织内容每个单元默认占卡片内容区宽度的 1/333.33%并自动换行排列网格单元之间通过**细边框box-shadow 模拟的 1px 分割线**进行视觉分隔形成类似宫格的观感每个网格单元可以独立设置style、className并可独立控制是否开启 hover 上浮效果。这一模式特别适合一个卡片承载多个入口/多块内容的场景例如功能入口矩阵、指标看板、设置面板分区等无需引入额外的栅格布局组件即可实现整齐的网格排版。二、Demo 演示与完整代码官方在 grid-card.tsx 中给出了最典型的使用示例该示例被 grid-card.md 以 Demo 形式挂载到文档页对应 index.en-US.md 中的 Grid card 条目import React from react; import { Card } from antd; const gridStyle: React.CSSProperties { width: 25%, textAlign: center, }; const App: React.FC () ( Card titleCard Title Card.Grid style{gridStyle}Content/Card.Grid Card.Grid hoverable{false} style{gridStyle} Content /Card.Grid Card.Grid style{gridStyle}Content/Card.Grid Card.Grid style{gridStyle}Content/Card.Grid Card.Grid style{gridStyle}Content/Card.Grid Card.Grid style{gridStyle}Content/Card.Grid Card.Grid style{gridStyle}Content/Card.Grid /Card ); export default App;这个 Demo 演示了两个关键点自定义单元宽度通过style{{ width: 25% }}将每个网格单元宽度改为卡片的 1/4默认是 1/37 个单元会在卡片内容区以flex-wrap自动换行排列前 4 个一行后 3 个一行关闭 hover 效果第二个Card.Grid通过hoverable{false}显式关闭了默认的悬停上浮效果其余网格保持默认的hoverable行为。从快照测试 demo.test.ts.snap 中可以验证该 Demo 的渲染结果卡片容器得到ant-card ant-card-bordered ant-card-contain-grid类名网格单元则渲染为ant-card-grid其中未显式设置hoverable{false}的单元带ant-card-grid-hoverable类hoverable{false}的单元不带该类。三、Card.Grid 属性详解依据 index.en-US.md 中Card.Grid一节的 API 表格并结合 Grid.tsx 源码Card.Grid支持以下属性属性说明类型默认值版本className网格容器的类名string--hoverable悬停时是否上浮lift upbooleantrue-style网格容器的内联样式CSSProperties--prefixCls自定义前缀类名源码支持string--CardGridProps在源码中的完整定义为// components/card/Grid.tsx export interface CardGridProps extends React.HTMLAttributesHTMLDivElement { prefixCls?: string; className?: string; hoverable?: boolean; style?: React.CSSProperties; }值得注意的细节hoverable默认为true与Card本身的hoverable默认false不同Card.Grid的悬停上浮默认开启。这是源码中hoverable true的默认参数决定的由于CardGridProps继承了React.HTMLAttributesHTMLDivElement它还支持所有原生div属性如id、onClick、data-*等因此网格单元可以天然作为可点击入口每个网格单元渲染为独立的div元素内容可以是任意 ReactNode。四、复合组件挂载Card.Grid 从哪来Card.Grid并不是魔法而是通过**复合组件Compound Component**模式静态挂载到Card上的。在 index.tsx 中可以清晰看到挂载过程// components/card/index.tsx import InternalCard from ./Card; import Grid from ./Grid; import Meta from ./Meta; type InternalCardType typeof InternalCard; export interface CardInterface extends InternalCardType { Grid: typeof Grid; Meta: typeof Meta; } const Card InternalCard as CardInterface; Card.Grid Grid; Card.Meta Meta;因此Card.Grid与Card.Meta一样是Card的静态属性使用前无需单独 importGrid组件直接在Card内书写Card.Grid即可Tree-shaking 也天然友好。五、源码级实现原理isContainGrid 与 contain-grid 布局Card.Grid真正巧妙之处在于其自动识别与布局切换逻辑实现在 Card.tsx 中1. 自动检测是否包含 Grid 子节点Card 组件通过React.Children.forEach遍历直接子节点判断其中是否存在类型为Grid的元素// components/card/Card.tsx第 148-156 行 const isContainGrid React.useMemoboolean(() { let containGrid false; React.Children.forEach(children as React.ReactElement, (element: JSX.Element) { if (element?.type Grid) { containGrid true; } }); return containGrid; }, [children]);只要子节点中出现Card.GridisContainGrid即为true从而在类名上添加ant-card-contain-grid[${prefixCls}-contain-grid]: isContainGrid,2. contain-grid 专属布局样式ant-card-contain-grid这一语义化类名会在 样式实现 中触发专门的布局规则// components/card/style/index.tsgenCardStyle 中 [${componentCls}-contain-grid]: { borderRadius: ${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0 , [${componentCls}-body]: { display: flex, flexWrap: wrap, }, [:not(${componentCls}-loading) ${componentCls}-body]: { marginBlockStart: token.calc(token.lineWidth).mul(-1).equal(), marginInlineStart: token.calc(token.lineWidth).mul(-1).equal(), padding: 0, }, },这解释了 Demo 中的排版行为卡片 body 变为display: flex; flex-wrap: wrap的弹性布局容器网格单元按顺序横向排列、放不下时自动换行通过负 margin 抵消网格边框导致的偏移并去掉 body 内边距使网格与卡片边缘对齐当loading为真时此时渲染 Skeleton 骨架屏上述内边距修正不生效避免加载态下布局错乱。3. 网格单元默认样式与分割线genCardGridStyle定义了网格单元的默认外观// components/card/style/index.tsgenCardGridStyle { width: 33.33%, padding: cardPaddingBase, // 默认取 token.paddingLG24px border: 0, borderRadius: 0, boxShadow: ${unit(lineWidth)} 0 0 0 ${colorBorderSecondary}, 0 ${unit(lineWidth)} 0 0 ${colorBorderSecondary}, ${unit(lineWidth)} ${unit(lineWidth)} 0 0 ${colorBorderSecondary}, ${unit(lineWidth)} 0 0 0 ${colorBorderSecondary} inset, 0 ${unit(lineWidth)} 0 0 ${colorBorderSecondary} inset; , transition: all ${token.motionDurationMid}, -hoverable:hover: { position: relative, zIndex: 1, boxShadow: cardShadow, // 默认取 token.boxShadowCard }, }三个关键实现细节默认宽度 1/3未设置style.width时网格单元占卡片内容区 33.33%三列排列Demo 通过width: 25%覆盖为四列分割线不用 border 而是 box-shadow通过四组 1px 的box-shadow上、下、左、右各一组配合inset精确绘制单元格之间的细分隔线这与直接使用border相比能避免双边框叠加问题hover 上浮hoverable为真时添加ant-card-grid-hoverable类:hover状态下提升z-index: 1并将阴影替换为cardShadow卡片阴影 token实现上浮视觉反馈transition负责阴影过渡动画。从源码注释可以看到卡片头部还通过marginBottom: -1修正了网格溢出的历史 bug对应注释 Fix card grid overflow bug可见该模式在细节上经过专门打磨。六、源码中与 Card.Grid 相关的其他细节组件 Token 支撑网格宽度分割线颜色、内边距等均来自设计令牌例如cardPaddingBase合并自token.paddingLG、colorBorderSecondary分割线颜色、cardShadow合并自token.boxShadowCard可通过 ConfigProvider 的主题 Token 全局调整相关定义见 style/index.ts 的prepareComponentToken与mergeToken类型导出CardGridProps已从 index.tsx 通过export type { CardGridProps } from ./Grid对外导出需要强类型书写时可直接引入快照测试保障该 Demo 的渲染结果被 demo.test.ts.snap 以快照形式固化任何 DOM 结构与类名的变更都会被测试捕获保证了该模式的行为稳定性。七、进阶实践建议基于 Demo 与源码分析在实际项目中可以这样用好Card.Grid控制每行列数通过style.width设置百分比宽度如25%为 4 列、33.33%为 3 列、50%为 2 列并配合textAlign、padding等样式微调内容排版可点击入口利用CardGridProps继承原生 div 属性直接在Card.Grid上绑定onClick或将链接、Button放入网格内容即可把网格单元变成功能入口选择性 hover对不需要悬停反馈的单元显式设置hoverable{false}如纯展示型单元其余保持默认即可与 Card 其它能力组合Card.Grid可作为Card的直接子节点与title、extra、actions、Card.Meta等能力自由组合构建头部 宫格 底部操作的完整信息面板主题定制如需全局调整网格间距或分割线颜色可通过主题 Token如colorBorderSecondary、paddingLG统一配置避免逐单元写死样式。八、总结Card.Grid是 ant-design 提供的一种轻量、优雅的卡片内容区隔方案无需额外引入栅格组件仅凭Card.Grid 百分比width即可实现整齐的宫格排版并通过hoverable控制悬停上浮反馈。其底层由复合组件挂载index.tsx→ 子节点自动检测Card.tsx→contain-grid弹性布局与 box-shadow 分割线样式style/index.ts三级机制协同完成行为稳定、可定制性强是构建功能矩阵、数据看板类卡片的实用选择。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →