Angular Material 组件:官方 Material Design 库
Angular Material 组件入门指南
Angular Material 是 Angular 官方提供的 Material Design 组件库。它包含一系列高质量、可复用、遵循 Google Material Design 规范的 UI 组件,能帮助你快速构建风格统一的现代 Web 应用。
本教程面向初学者,从零开始带你掌握 Angular Material 的核心概念与实际开发方法。
环境准备与安装
前提条件
- Node.js(建议 16 或以上版本)
- npm 或 yarn 包管理器
- Angular CLI(建议最新版
npm install -g @angular/cli) - 一个 Angular 项目(新项目或现有项目)
第一步:创建或进入项目
# 新建一个 Angular 项目(如果不打算使用当前项目)
ng new my-material-app --routing --style css
cd my-material-app
第二步:安装 Angular Material
在项目根目录运行:
ng add @angular/material
CLI 会引导你完成以下配置选项:
- 选择预定义主题(如 Indigo/Pink、Deep Purple/Amber 等)
- 是否设置全局 Angular Material 排版样式
- 是否启用浏览器动画(Animations)
安装完成后,会自动更新 angular.json、package.json 以及根样式文件。
检查关键文件变化
src/styles.css中会生成主题字体图标引用(通常是 Material Icons)src/app/app.module.ts会自动导入BrowserAnimationsModule或NoopAnimationsModule
核心组件概览
Angular Material 提供了超过 30 种组件,按功能可分为以下几类。每个组件都独立封装在对应的 MatXxxModule 中,可按需导入。
表单控件
| 组件 | 说明 |
|---|---|
MatInput |
标准输入框,支持 label、错误状态 |
MatAutocomplete |
带自动完成建议的输入框 |
MatDatepicker |
日期选择器 |
MatSelect |
选择器(下拉菜单) |
MatCheckbox |
复选框 |
MatRadioButton |
单选按钮组 |
MatSlideToggle |
滑动开关 |
MatSlider |
滑块 |
导航组件
| 组件 | 说明 |
|---|---|
MatToolbar |
顶部工具栏,常放标题、菜单按钮 |
MatSidenav |
侧边导航抽屉 |
MatMenu |
菜单面板(下拉菜单) |
MatTabs |
标签页导航 |
布局组件
| 组件 | 说明 |
|---|---|
MatCard |
卡片容器,适合展示分组内容 |
MatDivider |
分割线 |
MatExpansionPanel |
可展开/折叠面板 |
MatGridList |
网格列表,响应式排列单元格 |
MatList |
列表,支持导航、选择等模式 |
按钮与指示器
| 组件 | 说明 |
|---|---|
MatButton |
多种变体:raised、flat、stroked 等 |
MatButtonToggle |
切换按钮组(单选/多选) |
MatChips |
标签/碎片组件 |
MatIcon |
Material 图标展示 |
MatProgressSpinner |
加载圆形进度条 |
MatProgressBar |
线性进度条 |
弹出框与模态框
| 组件 | 说明 |
|---|---|
MatDialog |
模态对话框,可包含任意内容 |
MatTooltip |
鼠标悬停提示 |
MatSnackBar |
底部浮层消息提示 |
MatBottomSheet |
底部滑出面板 |
数据表
| 组件 | 说明 |
|---|---|
MatTable |
支持排序、分页、过滤的数据表格 |
MatPaginator |
分页器 |
MatSort |
排序头,常与 MatTable 搭配使用 |
快速上手:构建一个登录表单
我们将用以下组件构建一个简单的登录页面:
MatCard作为容器MatFormField+MatInput处理邮箱和密码MatButton用于登录操作MatIcon装饰输入框MatSnackBar显示反馈消息(模拟)
1. 导入所需模块
在 app.module.ts 中导入:
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatSnackBarModule } from '@angular/material/snack-bar';
@NgModule({
imports: [
// ... 其他模块
MatCardModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatSnackBarModule
]
})
export class AppModule { }
2. 编写模板 (app.component.html)
<div class="login-container">
<mat-card>
<mat-card-header>
<mat-card-title>欢迎登录</mat-card-title>
</mat-card-header>
<mat-card-content>
<form (ngSubmit)="onLogin()" class="login-form">
<mat-form-field appearance="outline" class="full-width">
<mat-label>邮箱</mat-label>
<input matInput type="email" placeholder="user@example.com" [(ngModel)]="email" name="email" required>
<mat-icon matSuffix>email</mat-icon>
</mat-form-field>
<mat-form-field appearance="outline" class="full-width">
<mat-label>密码</mat-label>
<input matInput type="password" [(ngModel)]="password" name="password" required>
<mat-icon matSuffix>lock</mat-icon>
</mat-form-field>
<button mat-raised-button color="primary" type="submit" class="full-width">
登录
</button>
</form>
</mat-card-content>
</mat-card>
</div>
3. 组件逻辑 (app.component.ts)
import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
email = '';
password = '';
constructor(private snackBar: MatSnackBar) {}
onLogin() {
// 模拟登录逻辑
if (this.email && this.password) {
this.snackBar.open('登录成功(演示效果)', '关闭', { duration: 3000 });
} else {
this.snackBar.open('请填写邮箱和密码', '关闭', { duration: 3000 });
}
}
}
4. 添加样式 (app.component.css)
.login-container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #f5f5f5;
}
mat-card {
width: 400px;
}
.full-width {
width: 100%;
margin-bottom: 16px;
}
这样就完成了一个响应式、美观的登录表单。引入 Angular Material 后,UI 细节(如输入框浮动标签、按钮波纹等)全部自动完成,开发效率极高。
高级技巧与最佳实践
定制主题
若预定义主题不满足需求,可自定义 SCSS 主题:
@use '@angular/material' as mat;
// 定义调色板
$my-primary: mat.define-palette(mat.$indigo-palette);
$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
$my-warn: mat.define-palette(mat.$red-palette);
// 创建主题
$my-theme: mat.define-light-theme((
color: (
primary: $my-primary,
accent: $my-accent,
warn: $my-warn,
)
));
// 应用主题
@include mat.all-component-themes($my-theme);
也支持将暗黑主题嵌套在特定 CSS 类下。
响应式设计
Angular Material 的布局组件(如 MatGridList)自带响应式能力。结合 Angular Flex Layout(另一个官方库)或 CSS Grid / Flexbox,可轻松实现跨设备适配。
无障碍性 (a11y)
- 所有组件均遵循 WAI-ARIA 标准。
- 使用
MatFormField的hintLabel、errorStateMatcher提供辅助提示。 - 配合
@angular/cdk/a11y相关工具增强键盘导航和焦点管理。
性能优化
- 按需导入模块:只导入使用到的
MatXxxModule,避免全量引入。 - 不使用
MatNativeDateModule等未用模块。 - Angular 的提前编译 (AOT) 和 Tree Shaking 会自动移除未使用的引用。
- 懒加载对话组件:通过
MatDialog的open方法传入组件,该组件所在模块会被懒加载。
常见问题解答
Q: 为什么我的图标显示不出来?
A: 需要在 index.html 中引入 Material Icons 字体:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
或在 angular.json 的 styles 中添加路径。
Q: 对话框/工具提示为什么不显示?
A: 检查是否在模块中导入了相应的 MatDialogModule、MatTooltipModule。同时确保应用支持浏览器动画(BrowserAnimationsModule)。
Q: 如何使用 Angular Material 的 CDK(组件开发工具)?
A: CDK 提供许多底层工具(如 Overlay、Portal、Drag & Drop),可通过 @angular/cdk 单独导入,帮助构建自定义组件。
Q: 如何升级到最新版本?
A: 使用 ng update @angular/material 自动升级,注意查看官方升级指南以应对破坏性变更。
结语与进一步学习
Angular Material 大幅降低了实现 Material Design 的门槛,与 Angular 深度集成,代码精简且文档完善。通过本教程,你已掌握安装、组件分类、实战使用以及最佳实践。
推荐学习资源:
- Angular Material 官方文档
- Angular CDK 指南
- 实战尝试:使用更多组件搭建个人博客或后台管理页面。
现在,打开你的编辑器,试试用 Angular Material 构建下一个项目吧!