Angular中使用*ngFor实现多行多列表格视图的优雅方案
Angular 下用*ngFor实现固定列数网格的规范实现
有两种主流的标准方案,根据场景选就行,都比硬写百分比宽度的hack方式维护性更好。
方案1:CSS Grid 布局(优先推荐)
这是目前前端实现规整网格的标准方案,完全不需要修改原数组结构,也不用写复杂的索引计算逻辑,靠CSS原生能力就能自动完成排布。
- 先给容器加网格样式:
.grid-wrap { display: grid; /* 10列等宽,要改列数直接改第一个参数即可 */ grid-template-columns: repeat(10, 1fr); /* 单元格间距,按需调整 */ gap: 6px; } .grid-cell { /* 按需给单元格加样式,比如设为正方形 */ aspect-ratio: 1; border: 1px solid #e5e7eb; display: flex; align-items: center; justify-content: center; }
- 模板里直接遍历原一维数组即可,不需要额外套循环:
<div class="grid-wrap"> <div class="grid-cell" *ngFor="let item of targetArray; let idx = index"> {{ idx + 1 }} </div> </div>
这个方案的优势:
- 零逻辑侵入,不需要对原长度100的数组做任何拆分转换
1fr单位会自动计算列宽,不会出现百分比宽度下padding、border导致的换行、溢出问题- 适配响应式非常方便,比如要做小屏5列大屏10列,只需要加媒体查询改
grid-template-columns参数,不需要动JS逻辑
方案2:二维数组拆分 + table 标签(仅适合语义化表格场景)
如果你的内容本身就是严格的表格数据,需要用原生table的语义,可以先把一维数组按列数拆成二维数组,再嵌套两层*ngFor渲染。
- 组件内先做数组转换:
// 你的原数组,长度100 targetArray = new Array(100); // 拆分后的二维表格数据 tableData: any[][]; // 每行列数 colNum = 10; ngOnInit() { this.tableData = []; for (let i = 0; i < this.targetArray.length; i += this.colNum) { this.tableData.push(this.targetArray.slice(i, i + this.colNum)); } }
- 模板嵌套遍历渲染表格:
<table class="data-table"> <tr *ngFor="let row of tableData"> <td *ngFor="let cell of row"> {{ cell }} </td> </tr> </table>
- 表格基础样式:
.data-table { width: 100%; border-collapse: collapse; } .data-table td { border: 1px solid #e5e7eb; padding: 8px; text-align: center; }
注意:如果只是普通卡片、按钮类的布局网格,不要用table,优先选CSS Grid方案,避免table默认样式带来的兼容问题,也更符合布局语义。
不推荐的做法
- 硬给元素加
width: 10%的百分比方案:一旦加边框、内边距、单元格外间距,总宽度就会超出容器导致换行,就算加box-sizing: border-box也没法原生处理单元格间距,需要手动计算宽度,维护成本高 - 用浮动、
inline-block凑布局:需要额外处理清除浮动、行内元素空白间隙等历史遗留问题,属于已经被淘汰的布局hack手段
内容的提问来源于stack exchange,提问作者SinHovna
相关产品推荐
相关产品推荐

