You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中使用*ngFor实现多行多列表格视图的优雅方案

Angular 下用*ngFor实现固定列数网格的规范实现

有两种主流的标准方案,根据场景选就行,都比硬写百分比宽度的hack方式维护性更好。

方案1:CSS Grid 布局(优先推荐)

这是目前前端实现规整网格的标准方案,完全不需要修改原数组结构,也不用写复杂的索引计算逻辑,靠CSS原生能力就能自动完成排布。

  1. 先给容器加网格样式:
.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;
}
  1. 模板里直接遍历原一维数组即可,不需要额外套循环:
<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渲染。

  1. 组件内先做数组转换:
// 你的原数组,长度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));
  }
}
  1. 模板嵌套遍历渲染表格:
<table class="data-table">
  <tr *ngFor="let row of tableData">
    <td *ngFor="let cell of row">
      {{ cell }}
    </td>
  </tr>
</table>
  1. 表格基础样式:
.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:21:34