Angular Material 的步进器通过把内容拆分成一些逻辑步骤,提供了一个向导式的工作流。

Material 步进器基于 CDK 中的步进器 —— 它负责实现驱动步进式工作流的逻辑部分。而 Material 步进器扩展了 CDK 的步进器,让它具有 Material Design 的样式。

有两个步进器组件:mat-horizontal-steppermat-vertical-stepper。 他们可以用相同方式使用,唯一的区别是步进器的方向。

如果步进器的标签只是纯文本,那么可以使用 label 属性。

对于更复杂的标签,可以在 mat-stepmatStepLabel 指令中添加一个模板。

mat-horizontal-stepper 可以定义标签的位置。end 是默认值,而 bottom 会把它放在步骤图标的下面而不是侧面。这个行为是由 labelPosition 属性控制的。

如果你使用的是水平步进器,则可以使用 headerPosition 输入属性来控制步进器内容的位置。默认情况下,它位于内容的顶部,但也可以放在其下方。

有两个按钮指令用来支持不同步骤之间的导航:matStepperPreviousmatStepperNext

可以设置 mat-horizontal-steppermat-vertical-stepperlinear 属性来创建线性步进器,它会要求用户必须完成了前面的步骤才能继续。 对于每个 mat-step,都可以把它的 stepControl 属性设置为一个上级 AbstractControl 来检查该步骤的有效性。

有两种可能的方式。一种是使用单一表单进行步进,另一种是使用不同的表单进行步进。

或者,如果你不想使用 Angular 表单,也可以把 completed 属性传入每个步骤,这些步骤会阻止用户继续,直到这个属性变为 true。注意,如果同时设置了 completedstepControl,则 stepControl 优先。

当步进器使用单一表单时,matStepperPreviousmatStepperNext 所在的元素都应该设置为 type="button",以防止在完成了所有步骤之前提交该表单。

<form [formGroup]="formGroup">
  <mat-stepper formArrayName="formArray" linear>
    <mat-step formGroupName="0" [stepControl]="formArray.get([0])">
      ...
      <div>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    <mat-step formGroupName="1" [stepControl]="formArray.get([1])">
      ...
      <div>
        <button mat-button matStepperPrevious type="button">Back</button>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    ...
  </mat-stepper>
</form>
<mat-stepper orientation="vertical" linear>
  <mat-step [stepControl]="formGroup1">
    <form [formGroup]="formGroup1">
      ...
    </form>
  </mat-step>
  <mat-step [stepControl]="formGroup2">
    <form [formGroup]="formGroup2">
      ...
    </form>
  </mat-step>
</mat-stepper>

如果线性步进器中的某个步骤不是必须完成的,可以在那个 mat-step 上设置 optional 属性。

默认情况下,每个步骤都是可编辑的,也就是说用户可以回到前一个已经完成的步骤,并编辑他们的回复。可以设置 mat-stepeditable="true" 来修改这种默认行为。

默认情况下,如果步骤有效(在线性步进器的情况下)并且用户已经与该步骤交互过,则该步骤的 completed 属性会返回 true。但是,用户也可以按需设置 completed 属性来覆盖默认的 completed 行为。

默认情况下,步骤头中会通过 <mat-icon> 元素来设置 Material Design 中的 createdone 图标。 如果你要提供另一个图标集,则可以为要覆盖的图标单独设置 matStepperIcon。每个步骤的 indexactiveoptional 的值都可以通过模板变量进行访问:

注意,要想提供自定义图标,你不一定非要用 mat-icon 组件。

你可以使用 animationDuration 输入属性来控制步进器动画的持续时间。如果要完全禁用动画,可以通过将此属性设置为 0ms 来实现。

你可以随意设置某个步骤的状态。默认情况下,指定的状态会映射到一个图标。不过,你也同样可以像前面所说的那样去覆盖它。

为了使用自定义的步骤状态,你必须把 displayDefaultIndicatorType 选项添加到全局的默认步进器选项中。你可以通过在应用的根模块中给 STEPPER_GLOBAL_OPTIONS 令牌提供一个值来指定它。

@NgModule({
  providers: [
    {
      provide: STEPPER_GLOBAL_OPTIONS,
      useValue: { displayDefaultIndicatorType: false }
    }
  ]
})

如果要在用户移过一个尚未正确填写的步骤时显示错误,可以通过输入属性 errorMessage 设置错误信息。并且通过 STEPPER_GLOBAL_OPTIONS 令牌中的 showError 选项配置步进器显示错误的方式。请注意,由于 linear 步进器会阻止用户跳过无效的步骤,因此该设置不会影响标记为 linear 的步进器。

@NgModule({
  providers: [
    {
      provide: STEPPER_GLOBAL_OPTIONS,
      useValue: { showError: true }
    }
  ]
})

默认情况下,步进器将在初始化时渲染其所有内容。如果你有一些内容要推迟到打开特定步骤之前才渲染,你可以将其放入具有 matStepContent 属性的 ng-template 中。

如果你的应用支持多种屏幕并且步进器的布局不适合特定的屏幕尺寸,你可以动态控制其 orientation 以根据视口更改布局。

键盘快捷键 操作
左箭头 将焦点移至上一步标题。
右箭头 将焦点移至下一步标题。
回车 选择已获得焦点的步骤。
空格 选择已获得焦点的步骤。

步进器所用的标签是通过 MatStepperIntl 提供的。要想对这些消息进行本地化,可以在应用的根模块中提供它的一个带翻译值的子类。

@NgModule({
  imports: [MatStepperModule],
  providers: [
    {provide: MatStepperIntl, useClass: MyIntl},
  ],
})
export class MyApp {}

从无障碍性的角度看,步进器和选项卡视图是一样的,所以默认会为它指定 role="tablist"。 步骤的头可以点击,以选择该步骤,所以指定 role="tab",其内容可以在选中时展开,所以指定 role="tabpanel"。 步骤头的 aria-selected 属性和步骤内容的 aria-expanded 属性会根据其选中状态的变化进行自动设置。

步进器和每个步骤都应该通过 aria-labelaria-labelledby 给出一个有意义的标签。

在为小屏幕尺寸构建时更喜欢垂直步进器,因为水平步进器通常会占用更多的水平空间,从而引入水平滚动。具有多个滚动维度的应用程序会使某些用户更难以消费内容。有关构建基于视口大小调整其布局的步进器的示例,请参阅上面的响应式步进器部分

步进器通常会包含表单和表单控件。如果步进器表单中的验证错误阻止了移动到另一个步骤,请确保你的表单控件将错误消息传达给辅助技术。这有助于用户了解为什么他们不能前进到另一个步骤。你可以通过将 <mat-error><mat-form-field> 结合使用或使用 ARIA 实时区域来完成此操作。

当某个步骤包含表单验证错误时,MatStepper 将在步骤的标题中显示错误(如果指定过)。有关带有错误消息的步进器示例,请参阅错误状态部分。对于非线性步进器,当用户离开带有错误消息的步骤时,你应该使用 ARIA 实时区域来播报错误消息。