Angular Material 组件:官方 Material Design 库

FreeGuideOnline 最新 2026-06-15

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.jsonpackage.json 以及根样式文件。

检查关键文件变化

  • src/styles.css 中会生成主题字体图标引用(通常是 Material Icons)
  • src/app/app.module.ts 会自动导入 BrowserAnimationsModuleNoopAnimationsModule

核心组件概览

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 标准。
  • 使用 MatFormFieldhintLabelerrorStateMatcher 提供辅助提示。
  • 配合 @angular/cdk/a11y 相关工具增强键盘导航和焦点管理。

性能优化

  • 按需导入模块:只导入使用到的 MatXxxModule,避免全量引入。
  • 不使用 MatNativeDateModule 等未用模块
  • Angular 的提前编译 (AOT) 和 Tree Shaking 会自动移除未使用的引用。
  • 懒加载对话组件:通过 MatDialogopen 方法传入组件,该组件所在模块会被懒加载。

常见问题解答

Q: 为什么我的图标显示不出来?
A: 需要在 index.html 中引入 Material Icons 字体:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

或在 angular.jsonstyles 中添加路径。

Q: 对话框/工具提示为什么不显示?
A: 检查是否在模块中导入了相应的 MatDialogModuleMatTooltipModule。同时确保应用支持浏览器动画(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 构建下一个项目吧!