Angular Material MatGridList 完全指南:二维网格布局的 API 解析与源码实现原理 📅 发布时间:2026/9/12 16:40:16 👁 浏览次数: Angular Material MatGridList 完全指南二维网格布局的 API 解析与源码实现原理【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/componentsmat-grid-list是 Angular Material 提供的二维网格列表组件它把内容单元Tile按行列自动排布成基于网格的布局。本文以当前仓库中 goldens/material/grid-list/index.api.md 这一 API 报告为核心骨架结合 grid-list.md、组件源码与官方示例系统讲解MatGridListModule暴露的全部公开 API、cols/rowHeight/gutterSize/rowspan/colspan等核心配置的用法并深入到TileCoordinator与TileStyler的底层布局算法帮助你既会写、又懂原理能够独立排查自定义网格布局中的问题。组件概览一个 Tile 网格引擎mat-grid-list的本质是一个网格布局引擎开发者只需声明列数引擎会自动根据元素个数推算行数并为每个mat-grid-tile计算出精确的 CSS 尺寸与位置。这与普通的 Flex/Grid CSS 布局不同——Angular Material 是通过运行时算法tile-coordinator.ts tile-styler.ts把布局结果直接写成内联样式。API 报告确认了整个包对外开放的全部类型结构如下布局宿主MatGridList组件selectormat-grid-list单元格MatGridTile组件selectormat-grid-tile标题/页脚文本MatGridTileText组件selectormat-grid-tile-header, mat-grid-tile-footer辅助指令MatGridAvatarCssMatStyler、MatGridTileHeaderCssMatStyler、MatGridTileFooterCssMatStyler、MatLine模块MatGridListModule所有入口统一从 src/material/grid-list/index.ts 导出并通过 public-api.ts 公开其中TileCoordinator以私有符号ɵTileCoordinator形式额外导出仅供 grid-list harness 使用。最小可用示例仓库官方示例 grid-list-overview-example.html 给出了最简洁的用法mat-grid-list cols2 rowHeight2:1 mat-grid-tile1/mat-grid-tile mat-grid-tile2/mat-grid-tile mat-grid-tile3/mat-grid-tile mat-grid-tile4/mat-grid-tile /mat-grid-list对应的组件类只需导入并注册MatGridListModule见 grid-list-overview-example.tsimport {Component} from angular/core; import {MatGridListModule} from angular/material/grid-list; Component({ selector: grid-list-overview-example, styleUrl: grid-list-overview-example.css, templateUrl: grid-list-overview-example.html, imports: [MatGridListModule], }) export class GridListOverviewExample {}这段代码会把 4 个 tile 排成 2 列 × 2 行的网格每格保持2:1的宽高比。MatGridList网格容器与三个核心配置根据 API 报告MatGridList实现MatGridListBase、OnInit、AfterContentChecked三个接口并通过Input()暴露三个配置项cols、gutterSize、rowHeight。同时它还持有ContentChildren(MatGridTile)查询结果_tiles并在ngAfterContentChecked生命周期中每次内容变更后重算布局源码见 grid-list.ts。cols必须指定的列数cols是唯一必须提供的属性它决定网格有多少列行数由引擎根据列数与 tile 数量自动推导。从源码实现看cols的 setter 做了防御性处理grid-list.tsInput() get cols(): number { return this._cols; } set cols(value: NumberInput) { this._cols Math.max(1, Math.round(coerceNumberProperty(value))); }输入经coerceNumberProperty强制转为数字因此cols3字符串与[cols]3数字写法等价取整后与 1 比较取最大值即最少 1 列非法值0、负数、NaN不会导致布局崩溃如果cols缺失ngOnInit中的_checkCols()会直接抛错mat-grid-list: must pass in number of columns. Example: mat-grid-list cols3grid-list.ts。rowHeight三种行高模式rowHeight支持三种取值方式这也是 grid-list 最具特色的设计官方文档grid-list.md与源码中的_setTileStyler逻辑完全一致grid-list.ts模式写法示例说明对应实现类固定高度100px、5em、250单位可为px/em/rem不写单位时默认补pxFixedTileStyler宽高比4:3必须是冒号形式列宽:行高不能用小数RatioTileStyler自适应fit行高 容器可用高度 ÷ 总行数容器必须显式设置高度FitTileStyler缺省不设置默认按1:1宽高比RatioTileStyler(1:1)源码中normalizeUnits负责单位归一化检测字符串末尾是否带单位字符没有则追加pxtile-styler.ts。RatioTileStyler的构造函数会把4:3解析为parseFloat(4) / parseFloat(3)得到行高比例若用户传了不含冒号的畸形值会抛错tile-styler.ts。FixedTileStyler还会用cssCalcAllowedValue正则校验值是否可安全放入 CSScalc()表达式非法字符同样在开发模式下抛错。!-- 固定高度 100px -- mat-grid-list cols4 rowHeight100px…/mat-grid-list !-- 宽高比 3:1注意是冒号 -- mat-grid-list cols4 rowHeight3:1…/mat-grid-list !-- fit 模式外层容器需要确定高度 -- div styleheight: 500px mat-grid-list cols4 rowHeightfit…/mat-grid-list /divgutterSize缝隙宽度gutterSize控制 tile 之间的间距支持任意px/em/rem值缺省单位为px默认值是1px源码中_gutter字段初始化为1px见 grid-list.ts。mat-grid-list cols4 gutterSize12px…/mat-grid-list mat-grid-list cols4 gutterSize0.5em…/mat-grid-list值得注意的是网格边缘不产生 gutter。TileStyler.setStyle中计算列宽时使用的 gutter 分摊系数为(cols - 1) / colstile-styler.ts即每个 1×1 tile 只承担内部缝隙那部分宽度这与 CSSgap的行为一致。MatGridTile跨行跨列的单元格MatGridTile是网格中的单元格组件API 报告显示它暴露rowspan与colspan两个输入默认值均为 1分别控制纵向、横向跨越的格数grid-tile.ts。mat-grid-list cols4 mat-grid-tile普通格子/mat-grid-tile mat-grid-tile colspan2横向占 2 列/mat-grid-tile mat-grid-tile rowspan2纵向占 2 行/mat-grid-tile mat-grid-tile colspan2 rowspan22×2 大格子/mat-grid-tile /mat-grid-list规则与限制colspan不能超过cols否则TileCoordinator._findMatchingGap会抛错mat-grid-list: tile with colspan N is wider than grid with colsMtile-coordinator.tsrowspan没有上限超出当前总行数时引擎会为它自动补充行两个 span 都会经coerceNumberProperty取整并通过 host 绑定[attr.rowspan]/[attr.colspan]回显到 DOM这是为了支持 grid-list harness 读取属性见 grid-tile.ts。底层的贪心定位算法为什么rowspan会让实现变得复杂因为普通文档流无法表达一个格子占了两行这种空洞结构。仓库中的 tile-coordinator.ts 专门解决这个问题其核心思路源码注释已明确说明用一个长度等于列数的追踪数组tracker记录每一列当前被占用的行数值为 0 表示空格按传入顺序为每个 tile 寻找第一个足够宽的空隙贪心策略一旦找到就放置并标记占用换行时_nextRow把tracker每个元素减 1表示向下移动一行后各列距空闲又近了一步最终输出每个 tile 的(row, col)坐标供TileStyler生成定位样式。该算法保证了 tile 始终按声明顺序渲染同时正确处理 rowspan 造成的空洞回填。rowCountgetter 返回rowIndex 1rowspangetter 会额外把超出总行数的部分计入得到网格实际占用的总行跨度tile-coordinator.ts。三种 TileStyler 的差异化样式策略坐标算好后由TileStyler的三种子类写入最终样式tile-styler.tsFixedTileStyler直接以固定行高为基准用topheight定位列表总高为calc(行数 × 行高 (行数-1) × gutter)最终把height写回容器RatioTileStyler巧妙利用 CSS 百分比 padding/margin 相对包含块宽度计算的特性用paddingTopmarginTop实现宽高比——这是纯 CSS 保持长宽比的标准技法代码注释也引用了 W3C 盒模型规范列表总高通过容器的paddingBottom撑出FitTileStylerpercentHeightPerTile 100 / 总行跨度结合水平 gutter 分摊系数计算基高同样以topheight定位。所有尺寸与位置都以calc(...)表达式生成见calc辅助函数由浏览器原生计算因此精度高且无重排抖动。MatGridTile._setStyle直接写入style属性而非 HostBinding注释解释了原因避免触发 ExpressionChangedAfterItHasBeenChecked 错误grid-tile.ts。Tile 头部、页脚与头像MatGridTileText 与 CSS 指令API 报告中还有一组纯样式辅助成员它们不参与布局计算只为模板标记添加 Material 语义类名类名selector作用MatGridTileTextmat-grid-tile-header, mat-grid-tile-footer标题/页脚容器内部收集mat-line多行文本MatGridTileHeaderCssMatStylermat-grid-tile-header添加mat-grid-tile-header类MatGridTileFooterCssMatStylermat-grid-tile-footer添加mat-grid-tile-footer类MatGridAvatarCssMatStyler[mat-grid-avatar], [matGridAvatar]为头部/页脚中的头像添加mat-grid-avatar类MatLine[mat-line], [matLine]单行文本指令来自MatLineModule使用示例mat-grid-list cols2 mat-grid-tile mat-grid-tile-header div mat-grid-avatar阿/div div mat-line标题第一行/div div mat-line副标题/div /mat-grid-tile-header 主体内容 mat-grid-tile-footer div mat-line页脚说明/div /mat-grid-tile-footer /mat-grid-tile /mat-grid-list从模板结构看mat-grid-tile-header/mat-grid-tile-footer与 tile 内容并列放置通过绝对定位吸附在 tile 顶部/底部具体样式见 grid-list.scss。MatGridTileText在ngAfterContentInit中调用setLines收集MatLine内容为多行文本排版做准备grid-tile.ts。MatGridListModule 的依赖构成API 报告完整展示了MatGridListModule的声明与导出关系grid-list-module.ts声明并导出MatGridList、MatGridTile、MatGridTileText、三个 CSS 样式指令、MatLineModule额外导出BidiModule来自angular/cdk/bidi。这是因为布局方向依赖注入的Directionality服务——MatGridList在_layoutTiles时读取this._dir.value若为rtl则setColStyles改用right而非left定位grid-list.ts 与 tile-styler.ts从而原生支持阿拉伯语等从右到左布局。使用 standalone 组件时直接imports: [MatGridListModule]即可使用 NgModule 应用则在imports数组中加入MatGridListModule。主题样式方面grid-list 的 M2/M3 主题由 _grid-list-theme.scss 提供并分别适配 _m2-grid-list.scss 与 _m3-grid-list.scss。MAT_GRID_LIST 注入令牌grid-list-base.ts定义了内部注入令牌MAT_GRID_LIST与接口MatGridListBaseMatGridList以useExisting方式把自己提供出去MatGridTile再以{optional: true}注入它grid-list-base.ts。这个设计有两个作用一是避免模块间的循环依赖二是让 tile 能反查宿主网格。_layoutTiles中tiles.filter(tile !tile._gridList || tile._gridList this)的过滤逻辑即利用了这一点——当网格嵌套时外层只排布自己直属的 tilegrid-list.ts。无障碍与语义官方文档grid-list.md明确指出默认的语义策略默认纯装饰grid-list 默认不设置任何 role、ARIA 属性或键盘交互等价于页面上一组div。这要求开发者对网格内放置的交互内容按钮、链接等自行做无障碍处理展示非交互内容列表若网格用于呈现非交互的内容项列表应显式给 grid-list 加rolelist、每个 tile 加rolelistitemmat-grid-list cols3 rolelist mat-grid-tile rolelistitem条目 A/mat-grid-tile mat-grid-tile rolelistitem条目 B/mat-grid-tile /mat-grid-list可测试性官方 Harness仓库还提供了完整的组件测试基础设施 testing/grid-list-harness.ts 与 testing/grid-tile-harness.ts这是 API 报告中[attr.cols]/[attr.rowspan]/[attr.colspan]回显设计的重要用途测试代码无需触碰内联样式即可通过 DOM 属性断言网格配置。典型断言能力包括读取网格列数、gutter 尺寸以及 tile 的 rowspan/colspan 等过滤逻辑见 testing/grid-list-harness-filters.ts行为验证见 testing/grid-list-harness.spec.ts。单元测试覆盖矩阵可见 grid-list.spec.ts。使用建议与已知限制综合 API 报告、文档与源码整理出以下几点实战建议cols是唯一必填项漏写会在开发模式下抛错rowHeight、gutterSize均有默认值1:1与1px可按需覆盖fit模式必须给容器定高否则总行高除以行数没有确定基准布局会塌陷colspan总和不能超过cols这是唯一会直接抛错的运行时约束跨行虽然不限但会增加总行数性能模型布局计算在每次ngAfterContentChecked触发源码注释认为计算足够廉价可高频运行且目前cols不支持响应式断点切换源码中留有TODO(kara): Conditional (responsive) column count / row size与窗口尺寸变化重排的 TODO 注释需要自适应列数时应在组件层根据BreakpointObserver动态修改cols绑定RTL 已内置支持无需额外配置但需确保应用注入了DirectionalityBidiModule已随模块导出无障碍角色默认不设置属于有意设计请按内容性质手动补充role/ARIA。相关资源索引API 报告本文核心依据goldens/material/grid-list/index.api.md组件文档src/material/grid-list/grid-list.md组件实现src/material/grid-list/grid-list.ts、src/material/grid-list/grid-tile.ts布局算法src/material/grid-list/tile-coordinator.ts、src/material/grid-list/tile-styler.ts模块定义src/material/grid-list/grid-list-module.ts官方示例grid-list-overview-example.html测试与 Harnesssrc/material/grid-list/grid-list.spec.ts、src/material/grid-list/testing/grid-list-harness.ts【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考