4.1 Angular Material与组件库


文档摘要

4.1 Angular Material 与组件库 Angular Material 是官方组件库,实现 Material Design 规范,与 CDK(组件开发工具包)共同发布。主线看点有二:其一,Material 组件默认全部 OnPush,是第 3 章策略的大规模实战样本;其二,CDK 把"行为"与"样式"分离(虚拟滚动、拖拽、无障碍焦点陷阱都在 CDK),自定义设计的团队可以只用行为不要皮肤。 本节要拿下什么 第 3 章的优化清单里反复出现 OnPush,本节要拿下一个现成的、出厂就按 OnPush 生产的组件库: 用生成器接入 Material 并挑选主题,搭建表格+对话框+表单域的典型页面骨架。

4.1 Angular Material 与组件库

Angular Material 是官方组件库,实现 Material Design 规范,与 CDK(组件开发工具包)共同发布。主线看点有二:其一,Material 组件默认全部 OnPush,是第 3 章策略的大规模实战样本;其二,CDK 把"行为"与"样式"分离(虚拟滚动、拖拽、无障碍焦点陷阱都在 CDK),自定义设计的团队可以只用行为不要皮肤。

本节要拿下什么

第 3 章的优化清单里反复出现 OnPush,本节要拿下一个现成的、出厂就按 OnPush 生产的组件库:

  1. 用生成器接入 Material 并挑选主题,搭建表格+对话框+表单域的典型页面骨架。
  2. 解释 Material 组件默认 OnPush 对业务数据流的要求(输入必须不可变更新)。
  3. 区分 Material 与 CDK 的分工,在自定义设计下仅用 CDK 行为。
  4. 完成主题定制与无障碍基线的核对。

一、接入与页面骨架

# 接入并选择主题 ng add @angular/material

典型后台页三件套——数据表、新建对话框、表单域:

import { Component, inject } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatTableModule, MatButtonModule, MatDialogModule, MatInputModule, MatFormFieldModule } from '@angular/material'; import { MatInputModule as MI } from '@angular/material/input'; @Component({ selector: 'app-order-table', imports: [MatTableModule, MatButtonModule, MatDialogModule], template: ` <!-- 列定义与数据源:表格组件本身是 OnPush --> <table mat-table [dataSource]="rows"> <ng-container matColumnDef="orderNo"> <th mat-header-cell *matHeaderCellDef>单号</th> <td mat-cell *matCellDef="let o">{{ o.orderNo }}</td> </ng-container> <ng-container matColumnDef="amount"> <th mat-header-cell *matHeaderCellDef>金额</th> <td mat-cell *matCellDef="let o">{{ o.amount }}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayed"></tr> <tr mat-row *matRowDef="let row; columns: displayed;"></tr> </table> <button mat-button (click)="openCreate()">新建订单</button> ` }) export class OrderTableComponent { private dialog = inject(MatDialog); displayed = ['orderNo', 'amount']; rows: { orderNo: string; amount: number }[] = [ { orderNo: 'A-1', amount: 199 }, { orderNo: 'A-2', amount: 88 } ]; openCreate() { // 对话框:独立的组件实例 自带焦点陷阱与滚动锁 this.dialog.open(CreateOrderDialog); } }

二、默认 OnPush 的含义:数据纪律是入场券

Material 全部组件默认 OnPush,意味着喂给它们的数据必须符合第 3 章的契约。最常见的翻车现场:往表格的 dataSource 原地 push 数据行,表格纹丝不动。正解两选一:换出新数组;或使用框架的数据源对象,它内部以流的方式发射更新并自动标记检查。这不是 Material 的怪癖,而是它把性能契约做成了默认——用官方组件库的过程,就是被强制执行数据纪律的过程。业务组件照此办理,整棵树的检查成本同步下降。

⚠️ 坑:对话框与组件分属不同注入器层级,对话框里拿不到页面的依赖是常事;设计上对话框组件应自带所需数据输入,关闭时用关闭结果流回传(对话框引用的关闭事件)。

三、CDK:只要行为不要皮肤

自定义视觉规范的公司(品牌色、圆角、字体都不同)常见选择:不用 Material 皮肤,只用 CDK 行为层。本书已经用过的虚拟滚动(3.2 节)正是 CDK 产物。再加一个焦点管理的例子说明 CDK 的价值:

import { A11yModule, FocusTrapFactory } from '@angular/cdk/a11y'; import { inject } from '@angular/core'; // 无障碍焦点陷阱:对话框场景必配,键盘焦点不能跑到遮罩外 export class CreateOrderDialog { private trapFactory = inject(FocusTrapFactory); // 模板侧用指令形式:cdkTrapFocus 包住对话框内容 }

CDK 的模块清单值得通读一遍:滚动、拖拽、布局断点、树组件、文本域自动增高、无障碍。判断某个交互"自己写要多少行"之前先查 CDK,通常答案是"已经有了"。

图:Material 与 CDK 的分层关系

图:Material 与 CDK 的分层关系

四、案例:后台脚手架从零到一

背景:内部审批后台,两周内出可用版本,视觉无特殊要求。
操作:接入 Material 选默认主题;页面骨架用侧导航 + 数据表 + 新建对话框三件套;主题色经主题定制变量改成企业色;无障碍项核对键盘走查(对话框焦点陷阱、表格滚动容器的滚动条可达)。
结果:一周完成全部页面骨架,第二周专注业务逻辑;键盘与读屏基本项直接达标。
解读:组件库买回的不只是样式,还有默认 OnPush 的性能基线与默认无障碍基线——这两项自研的隐性成本常被低估。
变式:半年后品牌升级要求全套换肤——因为皮肤与行为本就分离(组件属性与主题变量控制视觉),换肤改主题层即可,业务代码零改动。

本节要点回顾

  • 三件套骨架:数据表、对话框、表单域覆盖后台八成页面场景。
  • OnPush 契约:Material 默认 OnPush,喂它不可变数据是入场券,原地修改必不刷新。
  • CDK 分层:行为与皮肤分离,品牌定制团队可只用行为自绘皮肤。
  • 隐性资产:性能基线与无障碍基线随组件库免费附赠。
  • 主线上的一环:官方组件库把第 3 章的最佳实践变成默认配置,生态的价值正在于此。

下一节配齐观测仪表:开发工具与扩展。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U