
本文详解如何使用 `rowspan` 属性让表格左侧的分类标签(如 label 1、label 2)垂直跨多行,避免重复渲染,匹配真实分组数据结构。核心在于预统计每组标签的行数,并在首次出现时设置 `rowspan`,后续同组行跳过该单元格渲染。
在构建分组型表格(如带左侧标签栏的配置表、指标报表或表单摘要)时,常见需求是:同一逻辑分组下的多行数据共享一个左侧标签,而非每行重复显示。HTML 原生支持通过
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
✅ 正确实现步骤
-
预统计每组标签的行数
使用 reduce 遍历原始数据,按 rowLabel 聚合计数,生成映射对象 numRowsByLabel:const numRowsByLabel = data.reduce((acc, row) => { acc[row.rowLabel] = (acc[row.rowLabel] || 0) + 1; return acc; }, {}); 逐标签遍历,内部按数据行渲染
外层 labels.map() 确保标签顺序可控;内层 data.map() 筛选归属当前标签的行,并仅在该组第一行渲染带 rowSpan 的,其余行跳过该列。 关键逻辑:用状态标记“是否首行”
注意:React 渲染函数需纯函数式,不可依赖闭包外变量。因此应在每次 label 循环内重置 isFirstRow = true,并在处理每行时更新:{labels.map((label) => { let isFirstRow = true; // ✅ 每个 label 独立作用域 return data .filter(row => row.rowLabel === label) .map((row, idx) => { const numRows = numRowsByLabel[label]; const shouldRenderLabelCell = isFirstRow; isFirstRow = false; // ✅ 标记已处理首行 return ( <tr key={`${label}-${idx}`}> {shouldRenderLabelCell && ( <td rowSpan={numRows} style={{ width: '33%', textAlign: 'center', borderRight: '1px solid #E1D9D6', fontSize: '9px' }}> {label} </td> )} <td style={{ width: '50%', paddingLeft: '5px', fontSize: '9px' }}>{row.key}</td> <td style={{ width: '50%', textAlign: 'right', paddingRight: '5px', fontSize: '9px' }}>{row.value}</td> </tr> ); }); })}⚠️ 注意事项
- key 必须唯一且稳定:推荐组合 label 与 idx(如 ${label}-${idx}),避免仅用数组索引(ndx),防止重排时 React Diff 异常。
-
rowSpan 值必须准确:若某标签实际对应 3 行,但 rowSpan="3" 却只渲染了 2 行
,末尾将留空导致布局错乱。务必确保 filter 后的行数与 numRowsByLabel[label] 严格一致。 - 样式兼容性:避免在
内嵌套 div 或使用 display: flex(会破坏表格盒模型)。所有样式应直接作用于 / ,保持语义化表格结构。 - 空标签防护:若 labels 数组包含无对应数据的标签,filter(...).length === 0 时需跳过整个 map,避免渲染空
。 ✅ 最终效果对比
问题代码(错误) 正确实现(rowSpan) 每行重复渲染 LABEL 1 → 布局冗余、语义混乱 LABEL 1 单元格 rowSpan="2",覆盖两行高度,视觉与语义统一 通过以上方法,你不仅能解决当前的渲染问题,还能构建可扩展的分组表格组件——未来支持排序、折叠、动态加载时,只需复用 numRowsByLabel 逻辑即可。记住:rowSpan 不是魔法,而是对数据分组关系的显式声明。
- 样式兼容性:避免在


















