我学完 Angular Material 了

掌握了基本的 Angular 知识之后,现在让我们写一些真正的 Angular 代码吧。本文介绍使用 Angular 构建前端工程的时候使用 Angular Material 组件库的相关知识。

1. Angular Material 组件库

  • 使用 nvm 安装 node@16.14.2
  • 在 node@16.14.2 环境下安装 14.x 版本的 angular 脚手架 npm install -g @angular/cli@14
  • 创建一个新项目 ng new demo && cd demo
  • 安装组件库:ng add @angular/material@13.0.0 并确保在控制台上看到如下所示的信息:
  • 启动:yarn start
  • 按照下图所示在 app.module.ts 中引入 material 提供的 button module. 注意其在 imports 中的顺序排在最后。
  • 删除 app.component.html 中的所有代码,然后输入以下内容。注意这里和 react 不一样,不需要遵守单一根标签的规则。
  • 上面就是在 Angular 项目中引入 Matrial 库的过程了。

2. 制作一个名为 Matrial 的 shared module

  • 首先,创建一个名为 material 的子组件 ng g m material
  • 然后将其中的代码修改成如下形式:
ts 复制代码
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

const MaterialComponents = [
  MatButtonModule,
]

@NgModule({
  imports: [MaterialComponents],
  exports:[MaterialComponents]
})
export class MaterialModule { }
  • 最后将 app.module.ts 中关于 material 相关的引入换成对刚才新建的 MaterialModule 的引入。修改之后的代码如下所示。
ts 复制代码
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MaterialModule } from './material/material.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MaterialModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  • 上述做法并不是多此一举,而是为了保证 app.module.ts 的干净整洁。

3. Material 中的 Typography

与此相关的概念是 typographic level. 体现在 class 上面,类似于 TailwindCSS, 通过一些预制的类名来修改文字的样式。Typography 是 Angular Material 的排版样式。这些样式通常用于设置文本的大小、行距和字体权重等。常见的如下所示:

html 复制代码
<div class="mat-display-4">This is display 4</div>
<div class="mat-display-3">This is display 3</div>
<div class="mat-display-2">This is display 2</div>
<div class="mat-display-1">This is display 1</div>
<div class="mat-headline">This is a heading for h1</div>
<div class="mat-title">This is a heading for h2</div>
<div class="mat-subheading-2">This is a heading for h3</div>
<div class="mat-subheading-1">This is a heading for h4</div>
<div class="mat-body-1">This is body text</div>
<div class="mat-body-2">This is bold body text</div>
<div class="mat-caption">This is caption text</div>

效果如下所示:

3.1 mat-typography 类

在Angular Material框架中,mat-typography 类名是一个特殊的类,它用于自动应用一系列预定义的排版样式到HTML元素。当你在一个祖先元素上添加 mat-typography 类时,它会改变该元素内部的一些标准HTML标签(如h1, h2, p等)的样式,使它们符合Material Design的排版规范。

具体来说,mat-typography 类会与Angular Material的排版CSS样式一起工作,自动调整以下元素的样式:

  • 标题元素 (h1, h2, h3, h4, h5, h6)
  • 段落 (p)
  • 列表 (ul, ol, li)
  • 强调文本 (strong, b)
  • 以及其他一些文本相关元素

这个类使得开发者可以很方便地将Material Design的排版风格应用到整个页面或者页面的某个部分,而无需单独为每个元素指定样式。要使用 mat-typography,你需要在你的Angular项目中包含Angular Material的排版CSS文件,并将 mat-typography 类添加到想要应用Material Design排版的元素上。

例如,如果你想让整个页面都采用Material Design的排版,你可以在<body>标签上添加这个类:

html 复制代码
<body class="mat-typography">
  <!-- 页面内容 -->
</body>

或者,如果你只想对页面的某个部分应用这种排版,你可以将该类添加到某个具体的<div>上:

html 复制代码
<div class="mat-typography">
  <!-- 部分页面内容 -->
</div>

为了使 mat-typography 类生效,你的项目需要正确引入Angular Material的CSS文件,并且你的Angular项目应该已经安装了Angular Material库。

4. Button

下图展示的是 Angular 中所有的 button 类型:

Attribute Description
mat-button Rectangular text button w/ no elevation
mat-raised-button Rectangular contained button w/ elevation
mat-flat-button Rectangular contained button w/ no elevation
mat-stroked-button Rectangular outlined button w/ no elevation
mat-icon-button Circular button with a transparent background, meant to contain an icon
mat-fab Circular button w/ elevation, defaults to theme's accent color
mat-mini-fab Same as mat-fab but smaller

5. button-toggle

具有状态的 button 组件。

html 复制代码
<div class="toggle-button">
  <mat-button-toggle #toggle checked>
    {{ toggle.checked }}
  </mat-button-toggle>
</div>

或者

html 复制代码
<div class="toggle-button">
  <mat-button-toggle #toggle disabled checked="false">
    {{ toggle.checked }}
  </mat-button-toggle>
</div>

上述代码中的 #toggle 有点像 react 中的 ref, 可以拿到绑定标签上面的状态。而 checked 则表示初始的默认状态为选中。你还可以使用 disabled 置灰按钮或者使用 disableRipple 来禁用默认的水波纹效果。

效果如下所示:

mat-button-toggle-group: 用来将 toggle button 组织起来的组。这是因为,显而易见的是 toggle button 可以实现 radio 或者 checkbox 的功能。

html 复制代码
<div class="toggle-button">
  <mat-button-toggle-group #toggleGroup="matButtonToggleGroup">
    <mat-button-toggle value="angualr">angular</mat-button-toggle>
    <mat-button-toggle value="react">react</mat-button-toggle>
    <mat-button-toggle value="vue">vue</mat-button-toggle>
  </mat-button-toggle-group>
  {{ toggleGroup.value }}
</div>

效果如下所示:

而在此基础之上实现多选是相当容易的,只需要在 group 标签上加上 multiple 即可。

<mat-button-toggle-group #toggleGroup="matButtonToggleGroup" multiple>

toggleGroup 相当于是 html 自用的变量,可以通过调用组件函数的方式将其值传递给组件,然后广播出去:

html 复制代码
<div class="toggle-button">
  <mat-button-toggle-group
    multiple
    #toggleGroup="matButtonToggleGroup"
    (change)="onToggleChange(toggleGroup.value)"
  >
    <mat-button-toggle value="angular">Angular</mat-button-toggle>
    <mat-button-toggle value="react">React</mat-button-toggle>
    <mat-button-toggle value="vue">Vue</mat-button-toggle>
  </mat-button-toggle-group>
</div>

在组件中接受然后广播出去:

ts 复制代码
import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @Output() toggleValueChanged = new EventEmitter<string>();
  title = 'demo';

  onToggleChange(value: string) {
    console.log('value--', value);
    this.toggleValueChanged.emit(value);
  }
}

6. Icons

使用 Material 的 Icon 模块。首当其冲的当然是要在我们的 MaterialModule 中引入然后将相应的模块暴露出去,这个模块就是 MatIconModule: import { MatIconModule } from '@angular/material/icon';

html 复制代码
<mat-icon
  aria-hidden="false"
  aria-label="Example home icon"
  fontIcon="home"
  color="primary"
></mat-icon>
<mat-icon matBadge="15" matBadgeColor="warn">home</mat-icon>

Badge

我们可以通过在 mat-icon 或者 button 或者 span 等其它标签上添加 matBadge="15" matBadgeColor="warn" 的方式设置 badge 的颜色和数字。也可以通过 matBadgePosition="below before" 设置 badge 出现的位置。通过 matBadgeSize="small" 设置 badge 的大小。

关于 color 可以设置的值有:export declare type ThemePalette = 'primary' | 'accent' | 'warn' | undefined;

下面这个实例实现了当 badge 的值小于 5 隐藏,大于等于 5 的时候显示的效果:

html 复制代码
<mat-icon
  [matBadge]="badgeCount"
  (click)="(handleClick)"
  matBadgeColor="primary"
  matBadgePosition="below after"
  matBadgeSize="small"
  >
ts 复制代码
  badgeCount = 1;
  handleClick() {
    this.badgeCount += 1;
  }

需要注意的是 matBadge 中不知可以写数字,还可以写任何文本。

7. Progress Spinner

对应的 module 的名称是 MatProgressSpinnerModule, 在使用之前记得引入这个模块。

使用 mat-spinner 做一个点击加载数据的时候出现 spin 等待的效果:

html 复制代码
<div class="container">
  <mat-spinner *ngIf="showSpin" color="accent" diameter="50"></mat-spinner>

  <mat-icon [matBadge]="badgeCount" matBadgeColor="warn" (click)="handleClick()"
    >home</mat-icon
  >
  <!-- <mat-progress-spinner value="34"></mat-progress-spinner> -->
</div>
ts 复制代码
import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @Output() toggleValueChanged = new EventEmitter<string>();
  title = 'demo';
  badgeCount = 1;
  showSpin = false;
  loadData() {
    this.showSpin = true;
    setTimeout(() => { this.showSpin = false; this.badgeCount += 1; }, 1000)
  }
  handleClick() {
    this.loadData();
  }
  // onToggleChange(value: string) {
  //   console.log('value--')
  //   this.toggleValueChanged.emit(value);
  // }
}

效果如下所示:

相关的 module 名叫 MatToolbarModule, 记得在使用之前引用。

css 复制代码
.nav-bar {
  display: flex;
  justify-content: space-between;
}

span {
  margin-left: 20px;
}
html 复制代码
<mat-toolbar color="primary" class="nav-bar">
  <div>Codevolution</div>
  <div>
    <span>Home</span>
    <span>About</span>
    <span>Help</span>
  </div>
</mat-toolbar>

效果嘎嘎好:

9. Sidenav

相关的 module 名叫 MatSidenavModule, 记得在使用之前引用。

下面的代码完成了一个展开或者收起侧边栏的功能:

html 复制代码
<mat-drawer-container class="example-container">
  <mat-drawer mode="side" [opened]="showSpin">Drawer content</mat-drawer>
  <mat-drawer-content
    >Main content
    <mat-button-toggle
      #toggle
      checked="false"
      color="primary"
      (change)="handleChange(toggle.checked)"
      >{{ toggle.checked ? "收起" : "展开" }}</mat-button-toggle
    >
  </mat-drawer-content>
</mat-drawer-container>

你可以通过 mode 属性设置 sidenav 的特性,这个值默认为 over. 也可以取值:export declare type MatDrawerMode = 'over' | 'push' | 'side'; 这个属性设置的本质山是 drawer 和 content 之间的相互关系。

可以给 mat-sidenav 上面设置 ref 然后使用这个 ref 上的方法控制侧边栏的打开或者关闭状态:

html 复制代码
<mat-drawer-container class="example-container">
  <mat-drawer #myBar mode="side" [opened]="showSpin">Drawer content</mat-drawer>
  <mat-drawer-content
    >Main content
    <mat-button-toggle
      #toggle
      checked="false"
      color="primary"
      (change)="handleChange(toggle.checked)"
      >{{ toggle.checked ? "收起" : "展开" }}</mat-button-toggle
    >

    <button (click)="myBar.open()">open</button>

    <button (click)="myBar.close()">close</button>
    <button (click)="myBar.toggle()">toggle</button>
  </mat-drawer-content>
</mat-drawer-container>

通过使用 ref 我们的 html 模板拥有了一定的自治权。

除此之外,这个组件在侧边栏打开或者关上的时候都会触发名为 opened 的事件,因此我们可以监听这个事件,将侧边栏的状态信息传递出去:(opened)="handleOpen(true)" (close)="handleOpen(false)"

相关的 module 名叫 MatMenuModule, 记得在使用之前引用。

menu 一般是绑定在一个 button 上面,当这个 button 点击的时候会弹出来。如果不是这样使用的,则不会被渲染出来。

html 复制代码
<mat-menu #appMenu="matMenu">
  <button mat-menu-item>Front-end</button>
  <button mat-menu-item>Back-end</button>
</mat-menu>

<button mat-flat-button [mat-menu-trigger-for]="appMenu">Menu</button>

效果如下所示:

还可以使用下面的方式生成多级菜单:

html 复制代码
<mat-menu #appMenu="matMenu" xPosition="after" yPosition="above">
  <button mat-menu-item [mat-menu-trigger-for]="subMenu">Front-end</button>
  <button mat-menu-item>Back-end</button>
</mat-menu>

<button mat-flat-button [mat-menu-trigger-for]="appMenu">Menu</button>

<mat-menu #subMenu="matMenu">
  <button mat-menu-item>Angular</button>
  <button mat-menu-item>React</button>
  <button mat-menu-item>Vue</button>
</mat-menu>

需要注意的有两点:一个是 mat-menu-trigger-for 的绑定;一个是代码组织结构不等于 dom 的组织结构。实际上在上面的代码中,最外层的就是 button, 菜单项是 button 的子节点。

更好看的菜单项:

html 复制代码
<button
  mat-icon-button
  [matMenuTriggerFor]="menu"
  aria-label="Example icon-button with a menu"
>
  <mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
  <button mat-menu-item>
    <mat-icon>dialpad</mat-icon>
    <span>Redial</span>
  </button>
  <button mat-menu-item disabled>
    <mat-icon>voicemail</mat-icon>
    <span>Check voice mail</span>
  </button>
  <button mat-menu-item>
    <mat-icon>notifications_off</mat-icon>
    <span>Disable alerts</span>
  </button>
</mat-menu>

菜单的延时加载以及在调用的时候动态传参:

html 复制代码
<mat-menu #lazyMenu="matMenu">
  <ng-template matMenuContent let-name="name" let-hobby="hobby">
    <button mat-menu-item>Settings</button>
    <button mat-menu-item>Hobby is {{ hobby }}</button>
    <button mat-menu-item>Log out {{ name }}</button>
  </ng-template>
</mat-menu>

<button
  mat-raised-button
  [matMenuTriggerData]="{ name: 'Vishwas', hobby: 'football' }"
  [matMenuTriggerFor]="lazyMenu"
>
  Vishwas
</button>

<button
  mat-raised-button
  [matMenuTriggerData]="{ name: 'codevolution', hobby: 'teaching' }"
  [matMenuTriggerFor]="lazyMenu"
>
  Codevolution
</button>

这段代码是使用了 Angular Material 组件库中的 mat-menu 组件来创建一个下拉菜单,并且这个菜单的内容是通过 ng-template 动态生成的。下面是对这段代码的详细解释:

1. <mat-menu #lazyMenu="matMenu">

这一行定义了一个 mat-menu 组件,它是一个下拉菜单。#lazyMenu="matMenu" 是一个模板引用变量,它允许我们在模板的其他部分引用这个菜单。

2. <ng-template matMenuContent let-name="name" let-hobby="hobby">

这里使用了一个 ng-template 标签来定义菜单的内容。matMenuContent 是一个指令,它告诉 Angular 这个模板是用来渲染 mat-menu 的内容的。

let-name="name" 和 let-hobby="hobby" 是模板输入变量的声明。这些变量将从触发菜单打开的数据(通过 [matMenuTriggerData] 传递)中获取对应的值。

3. 菜单项

html 复制代码
<button mat-menu-item>Settings</button>  
<button mat-menu-item>Hobby is {{hobby}}</button>  
<button mat-menu-item>Log out {{name}}</button>

这三行定义了三个菜单项。每个菜单项都是一个 button 元素,使用了 mat-menu-item 指令来将其标记为菜单项。

  • 第一个菜单项是静态的,只显示"Settings"文本。
  • 第二个菜单项显示"Hobby is "后跟从触发数据中获取的 hobby 值。
  • 第三个菜单项显示"Log out "后跟从触发数据中获取的 name 值。

4. 触发按钮

下面是两个按钮,它们都用作触发下拉菜单的按钮:

html 复制代码
<button mat-raised-button  
        [matMenuTriggerData]="{ name: 'Vishwas', hobby: 'football'}"  
        [matMenuTriggerFor]="lazyMenu">  
  Vishwas  
</button>

和

html 复制代码
<button mat-raised-button  
        [matMenuTriggerData]="{ name: 'codevolution', hobby: 'teaching'}"  
        [matMenuTriggerFor]="lazyMenu">  
  Codevolution  
</button>

这两个按钮都使用了 mat-raised-button 指令来应用 Material Design 的样式。

  • [matMenuTriggerData] 是一个属性绑定,它传递一个对象,该对象包含要显示在菜单中的数据(在这里是 name 和 hobby)。
  • [matMenuTriggerFor]="lazyMenu" 是一个属性绑定,它指定了当按钮被点击时要打开哪个菜单。在这里,它引用了之前定义的 mat-menu 组件的模板引用变量 lazyMenu。

这段代码创建了一个动态内容的下拉菜单,该菜单的内容(特别是 name 和 hobby)是根据触发菜单打开的按钮所传递的数据来确定的。当用户点击任何一个按钮时,都会打开一个包含该用户名字和爱好的菜单。

11. Lists

相关的 module 名叫 MatListModule, 记得在使用之前引用。

html 复制代码
<mat-list dense>
  <mat-list-item>item1</mat-list-item>
  <mat-list-item>item2</mat-list-item>
  <mat-list-item>item3</mat-list-item>
</mat-list>
<mat-nav-list dense>
  <a mat-list-item href="#"> Home </a>
  <a mat-list-item href="#"> About </a>
  <a mat-list-item href="#"> Services </a>
</mat-nav-list>

效果如图所示:

带图标的多行 list:

html 复制代码
<mat-list>
  <mat-list-item>
    <mat-icon matListIcon>home</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>
  <mat-list-item>
    <mat-icon matListIcon>menu</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>
  <mat-list-item>
    <mat-icon matListIcon>help</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>
</mat-list>

效果如下所示:

12. 分割符 MatDividerModule

使用列表等组件的时候,希望有更好的排列方式,这个时候一般使用的就是 MatDividerModule. 这个组件就是用来分割其它组件的。

下面是添加了分割符号的列表,比之前好看多了。

html 复制代码
<mat-list>
  <mat-list-item>
    <mat-icon matListIcon>home</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>
  <mat-divider></mat-divider>
  <mat-list-item>
    <mat-icon matListIcon>menu</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>

  <mat-divider></mat-divider>
  <mat-list-item>
    <mat-icon matListIcon>help</mat-icon>
    <h3 matLine>Heading</h3>
    <p matLine>Line</p>
  </mat-list-item>

  <mat-divider></mat-divider>
</mat-list>

效果如下:

13. Grids

相关的 module 名叫 MatGridListModule, 记得在使用之前引用。就是 CSS 中的 网格布局感觉。

html 复制代码
<mat-grid-list cols="2" rowHeight="fit" style="height: 200px" gutterSize="10px">
  <!-- <mat-grid-list cols="2" rowHeight="2:1"> -->
  <!-- <mat-grid-list cols="2" rowHeight="100px"> -->
  <mat-grid-tile colspan="1">Title 1</mat-grid-tile>
  <mat-grid-tile>Title 2</mat-grid-tile>
  <mat-grid-tile>Title 3</mat-grid-tile>
  <mat-grid-tile>Title 4</mat-grid-tile>
</mat-grid-list>

14. Expansion

相关的 module 名叫 MatExpansionModule, 记得在使用之前引用。这个是一个可以伸缩的标题栏。

html 复制代码
<mat-expansion-panel>
  <mat-expansion-panel-header>
    <mat-panel-title> Angular Fundamentals </mat-panel-title>
    <mat-panel-description> Total Duration: 3 hours </mat-panel-description>
  </mat-expansion-panel-header>
</mat-expansion-panel>

效果如下所示:

添加内容和按钮之后:

html 复制代码
<mat-expansion-panel>
  <mat-expansion-panel-header>
    <mat-panel-title> Angular Fundamentals </mat-panel-title>
    <mat-panel-description> Total Duration: 3 hours </mat-panel-description>
  </mat-expansion-panel-header>
  <p>This is the pannel content. Add course details.</p>
  <mat-action-row>
    <button mat-button>Enroll</button>
  </mat-action-row>
</mat-expansion-panel>

Expansion 组:如果我们使用 mat-accordion 包裹多个 mat-expansion-panel 在内,那么这些被包裹的 expansion-panel 会被认为是同一组。在同一个组里面的 panel 具有一个特性就是,其它 panel 展开的时候,剩余 panel 会收起来。

html 复制代码
<mat-accordion>
  <mat-expansion-panel>
    <mat-expansion-panel-header>
      <mat-panel-title> Angular Fundamentals </mat-panel-title>
      <mat-panel-description> Total Duration: 3 hours </mat-panel-description>
    </mat-expansion-panel-header>
    <p>This is the pannel content. Add course details.</p>
    <mat-action-row>
      <button mat-button>Enroll</button>
    </mat-action-row>
  </mat-expansion-panel>
  <mat-expansion-panel>
    <mat-expansion-panel-header>
      <mat-panel-title> Angular Fundamentals </mat-panel-title>
      <mat-panel-description> Total Duration: 3 hours </mat-panel-description>
    </mat-expansion-panel-header>
    <p>This is the pannel content. Add course details.</p>
    <mat-action-row>
      <button mat-button>Enroll</button>
    </mat-action-row>
  </mat-expansion-panel>
</mat-accordion>

效果如下:

然而,如果不需要这个特性,可以简单的在 mat-accordion 这个外层标签上设置 multi="true" 即可!

而如果你需要隐藏右上角的 toggle 标签,只需要在 mat-accordion 这个外层标签上设置 hideToggle 即可!这个时候只需要点击每一个 panel 的标题栏即可展开或者收缩这个 panel.

15. Cards

相关的 module 名叫 MatCardModule, 记得在使用之前引用。这个是项目中经常会用到的卡片组件。

html 复制代码
<mat-card>Basic Card </mat-card>
<mat-divider></mat-divider>
<mat-card>
  <mat-card-title> Card Title </mat-card-title>
  <mat-card-content> This is card content. </mat-card-content>
  <mat-card-actions align="end">
    <button mat-flat-button color="primary">Login</button>
  </mat-card-actions>
</mat-card>

上面的代码是 Cards 组件简单的使用方法。其效果如下所示:

Material 中的这个 -actions 标签非常的有意思!

16. Tabs

相关的 module 名叫 MatTabsModule, 记得在使用之前引用。这个就是 Tabs 用来切换卡片的。

html 复制代码
<mat-tab-group
  #tabRef
  (selectedTabChange)="handleTabChange(tabRef.selectedIndex!)"
>
  <mat-tab label="Angular">Angular</mat-tab>
  <mat-tab label="React">React</mat-tab>
  <mat-tab label="Vue">Vue</mat-tab>
</mat-tab-group>
{{ tabRef.selectedIndex }}

上述代码完成了不同 tabs 之间的切换并且将当前选择的 tab 的序列号通过事件传递给了组件。

17. Stepper

相关的 module 名叫 MatStepperModule, 记得在使用之前引用。

html 复制代码
<mat-horizontal-stepper>
  <mat-step label="Shipping Address">
    <p>Shipping Address Details</p>
  </mat-step>
  <mat-step label="Billing Address">
    <p>Billing Address Details</p>
  </mat-step>
  <mat-step label="Place Order">
    <p>Order Details</p>
  </mat-step>
</mat-horizontal-stepper>

效果如下所示:

只能说确实 cool!

我们可以通过在 stepper 中添加按钮并绑定特定属性的当时方便的实现前进和后退:

html 复制代码
<mat-horizontal-stepper>
  <mat-step label="Shipping Address">
    <p>Shipping Address Details</p>
  </mat-step>
  <mat-step label="Billing Address">
    <p>Billing Address Details</p>
    <div>
      <button mat-button matStepperPrevious>Previous</button>
      <button mat-button matStepperNext>Next</button>
    </div>
  </mat-step>
  <mat-step label="Place Order">
    <p>Order Details</p>
  </mat-step>
</mat-horizontal-stepper>

可以看到第二步里面出现了两个按钮:

通过 completed 和 linear 属性可以控制 stepper 能否向下走:

html 复制代码
<mat-horizontal-stepper linear="">
  <mat-step label="Shipping Address" completed="false">
    <p>Shipping Address Details</p>
  </mat-step>
  <mat-step label="Billing Address" completed="false">
    <p>Billing Address Details</p>
    <div>
      <button mat-button matStepperPrevious>Previous</button>
      <button mat-button matStepperNext>Next</button>
    </div>
  </mat-step>
  <mat-step label="Place Order" completed="false">
    <p>Order Details</p>
  </mat-step>
</mat-horizontal-stepper>

在代码中,我们设置 linear 表示要前面的步骤完成了后面的步骤才会显示出来。同时设置 completed 属性告诉组件哪个步骤完成了。

此外,我们可以给 mat-step 上添加 optional 表示这一步是可选的。

除了有 mat-horizontal-stepper 还有 mat-vertical-stepper


下面的组件都是和表单相关的:

18. Input

我们需要引入的 module 有:MatFormFileModule 和 MatInputModule.

html 复制代码
<mat-form-field>
  <mat-label>Name</mat-label>
  <input matInput />
</mat-form-field>

通过 floatLabel 这个属性你可以关闭或者打开上面很酷的悬浮样式。

你可以设置其值为 never 或者 always.

你可以设置 input 上面的 required 属性,这样表示必填项。

注意 required 是设置在 input 上面的,而如果你的整个表单都不需要 * , 你可以在 mat-form-field 上面设置 hideRequiredMarker, 这样就算是必填项也不会将 * 显示出来。

我们还可以给 input 方便的添加 hint: <mat-hint align="end">Min 5 characters</mat-hint>

通过设置 mat-form-field 上面名为 appearance 属性的值为 legacy 或者 standard fill outline可以直接改变整个表单的样式。通过设置 color 属性可以直接改变整个表单的颜色 accent warn。

19. Select

我们需要引入的 module 有:MatSelectModule.

html 复制代码
<mat-form-field floatLabel="always" hideRequiredMarker="false">
  <mat-select>
    <mat-label>Topic</mat-label>
    <mat-option value="angular">Angular</mat-option>
    <mat-option value="react">React</mat-option>
    <mat-option value="vue">Vue</mat-option>
  </mat-select>
</mat-form-field>

双向绑定的 Select:

html 复制代码
<mat-form-field>
  <mat-label>Topic</mat-label>
  <mat-select [(value)]="selectedValue">
    <mat-option value="angular">Angular</mat-option>
    <mat-option value="react">React</mat-option>
    <mat-option value="vue">Vue</mat-option>
  </mat-select>
</mat-form-field>

{{ selectedValue }}

分组 Select:

html 复制代码
<mat-form-field>
  <mat-label>Topic</mat-label>
  <mat-select [(value)]="selectedValue">
    <mat-option>None</mat-option>
    <mat-optgroup label="Web">
      <mat-option value="angular">Angular</mat-option>
      <mat-option value="react">React</mat-option>
      <mat-option value="vue">Vue</mat-option>
    </mat-optgroup>
    <mat-optgroup label="Mobile">
      <mat-option value="ionic">Ionic</mat-option>
      <mat-option value="reactnative">React Native</mat-option>
    </mat-optgroup>
  </mat-select>
</mat-form-field>
{{ selectedValue }}

多选 Select,只需要在 mat-select 这个标签上设置 multiple 就可以完成多选了。

20. Autocomplete

我们需要引入的 module 有:MatAutocompleteModule. 这个组件的作用是对 input 进行了扩展,在输入的时候能够提供给用户方便的选项。

html 复制代码
<mat-form-field>
  <input type="text" matInput [matAutocomplete]="auto" />
  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let option of options" [value]="option">
      {{ option }}
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
{{ selectedValue }}

效果如下:

但是,如果我们的 options 不是简单的数组,而是具有复杂结构的数组,这个时候我们可以定义一个 displayFn 来定制解析数组中的数据:

ts 复制代码
  objOptions = [{
    name: 'angular',
  }, {
    name: 'react',
  }, {
    name: 'vue',
  }];
  displayFn(option: any) {
    return option.name;
  }
html 复制代码
<mat-form-field>
  <input type="text" matInput [matAutocomplete]="auto" />
  <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
    <mat-option *ngFor="let option of objOptions" [value]="option">
      {{ option.name }}
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
{{ selectedValue }}

注意上面的代码中用了 [displayWith]="displayFn"

21. FormsModule ReactiveFormsModule

这两个 module 记得在自己封装的 material module 之前引入,如下图所示:

然后来到我们的根组件中引入 FormControl:

ts 复制代码
import { FormControl } from '@angular/forms';
import { Observable, startWith, map } from 'rxjs';
...
myControl = new FormControl();
  filterOptions: Observable<string[]>;
  ngOnInit() {
    this.filterOptions = this.myControl.valueChanges.pipe(
      startWith(''),
      map(value => this._filter(value))
    )
  }

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.options.filter(option => option.toLowerCase().includes(filterValue))
  }

最后在 html 中使用表格的 controller:

html 复制代码
<mat-form-field>
  <input
    type="text"
    matInput
    [matAutocomplete]="auto"
    [formControl]="myControl"
  />
  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let option of filterOptions | async" [value]="option">
      {{ option }}
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
{{ selectedValue }}

对上面的代码进行解释:

21.1 TypeScript 代码部分

  1. 引入必要的模块:
ts 复制代码
import { FormControl } from '@angular/forms';
import { Observable, startWith, map } from 'rxjs';

这里引入了FormControl用于创建表单控件,并从rxjs中引入了Observable, startWith, 和 map用于处理异步数据流。

  1. 初始化FormControl和Observable:
ts 复制代码
myControl = new FormControl();
filterOptions: Observable<string[]>;
  • myControl是一个新的FormControl实例,它代表了一个表单输入控件。
  • filterOptions是一个Observable,它将包含过滤后的选项列表。
  1. 在ngOnInit生命周期钩子中设置数据流:
ts 复制代码
ngOnInit() {
  this.filterOptions = this.myControl.valueChanges.pipe(
    startWith(''),
    map(value => this._filter(value))
  )
}

在组件初始化时,ngOnInit方法会被调用。这里,我们监听myControl的值变化,并通过pipe操作符来处理这些变化。startWith('')确保在没有任何输入时也能触发一次数据流(即初始化时),map则用于将每次输入变化映射到过滤后的选项列表。

  1. 实现过滤函数:
ts 复制代码
private _filter(value: string): string[] {
  const filterValue = value.toLowerCase();
  return this.options.filter(option => option.toLowerCase().includes(filterValue))
}

_filter方法根据用户的输入来过滤options数组(这个数组应该在类的其他部分被定义和初始化)。过滤是通过将输入和选项都转换为小写,并检查每个选项是否包含输入的文本来实现的。

21.2 HTML 代码部分

  1. 使用Material的表单和自动完成组件:
html 复制代码
<mat-form-field>
  <input type="text" matInput [matAutocomplete]="auto" [formControl]="myControl" />
  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let option of filterOptions | async" [value]="option">
      {{ option }}
    </mat-option>
  </mat-autocomplete>
</mat-form-field>
  • <mat-form-field>是Material的表单字段组件。
  • <input>元素与FormControl实例(myControl)绑定,并设置为自动完成的输入源。
  • <mat-autocomplete>是Material的自动完成组件,它与输入字段相关联。
  • *ngFor指令用于循环遍历filterOptions中的每个选项(这里使用了async管道来处理Observable)。
  1. 显示选中的值:
html 复制代码
{{ selectedValue }}

这部分是显示选中的值,但需要注意的是,selectedValue变量在提供的代码片段中没有定义。通常,你需要在组件的TypeScript部分添加一个[(ngModel)]绑定或在选项被选中时更新这个值。如果要在选项被选中时更新selectedValue,你可以使用(optionSelected)事件。例如:

html 复制代码
<mat-autocomplete (optionSelected)="selectedValue = $event.option.value">

这样,每当用户从自动完成列表中选择一个选项时,selectedValue就会被更新为该选项的值。

这段代码实现了一个基于用户输入的实时过滤的自动完成功能,使用了Angular Material的组件和Reactive Forms的FormControl。

22. Checkbox

我们需要引入的 module 有:MatCheckboxModule.

html 复制代码
<mat-checkbox> Subscribe </mat-checkbox>
<br />
<mat-checkbox labelPosition="before"> Subscribe </mat-checkbox>
<br />
<mat-checkbox color="primary"> Subscribe </mat-checkbox>
<br />
<mat-checkbox color="warn"> Subscribe </mat-checkbox>

Radio

我们需要引入的 module 有:MatRadioModule.

html 复制代码
<mat-radio-group>
  <mat-radio-button value="angular" color="primary">Angular</mat-radio-button>
  <mat-radio-button value="react" color="primary">React</mat-radio-button>
  <mat-radio-button value="vue" color="warn">Vue</mat-radio-button>
</mat-radio-group>

我们用 group 将它们包裹起来它们自己就互斥了!

23. Datepicker

我们需要引入的 module 有:MatDatepickerModule 和 MatNativeDateModule.

基本使用:

html 复制代码
<mat-form-field>
  <input matInput [matDatepicker]="myDatePicker" />
  <mat-datepicker-toggle [for]="myDatePicker" matSuffix></mat-datepicker-toggle>
  <mat-datepicker #myDatePicker startView="multi-year"></mat-datepicker>
</mat-form-field>

效果:

设置日期的上下限:

html 复制代码
<mat-form-field>
  <input
    matInput
    [matDatepicker]="myDatePicker"
    [min]="minDate"
    [max]="maxDate"
  />
  <mat-datepicker-toggle [for]="myDatePicker" matSuffix></mat-datepicker-toggle>
  <mat-datepicker #myDatePicker startView="multi-year"></mat-datepicker>
</mat-form-field>
ts 复制代码
  minDate = new Date();
  maxDate = new Date(2024, 12, 31);

效果为:

设置日期过滤器:

html 复制代码
<mat-form-field>
  <input
    matInput
    [matDatepicker]="myDatePicker"
    [matDatepickerFilter]="dateFilter"
  />

  <mat-datepicker-toggle [for]="myDatePicker" matSuffix></mat-datepicker-toggle>
  <mat-datepicker #myDatePicker startView="multi-year"></mat-datepicker>
</mat-form-field>
ts 复制代码
  dateFilter = (date) => {
    const day = date.getDay();
    if (day !== 0 && day !== 6) {
      return date;
    } else {
      return null;
    };
  }

效果为:

24. Tooltip

Angular Material 是一套丰富的 UI 组件库,用于构建 Angular 应用程序。Tooltip 是其中的一个组件,它提供了一种方式来显示元素的辅助信息,通常当用户将鼠标悬停在某个元素上时显示。

下面是关于 Angular Material Tooltip 组件的一些关键点,包括如何设置位置、持续时间和内容:

1. 安装和导入

首先,确保你已经安装了 Angular Material,并在你的 Angular 项目中导入了 MatTooltipModule。

bash 复制代码
npm install @angular/material

然后在你的模块文件中导入 MatTooltipModule:

typescript 复制代码
import { MatTooltipModule } from '@angular/material/tooltip';
import { NgModule } from '@angular/core';

@NgModule({
  imports: [
    // 其他模块
    MatTooltipModule
  ],
  // ...
})
export class AppModule { }

2. 基本使用

在你的组件的 HTML 模板中,你可以这样使用 Tooltip:

html 复制代码
<button mat-button [matTooltip]="'这是 Tooltip 文本'">悬停我</button>

3. 设置 Tooltip 位置

Tooltip 组件提供了多种位置选项,你可以通过 matTooltipPosition 指令来设置 Tooltip 的位置。例如:

html 复制代码
<button mat-button [matTooltip]="'这是 Tooltip 文本'" [matTooltipPosition]="'above'">悬停我</button>

可用的位置有:

  • above:上方
  • below:下方
  • left:左侧
  • right:右侧
  • before:元素前
  • after:元素后

4. 设置 Tooltip 持续时间

Tooltip 的显示持续时间可以通过 matTooltipShowDelay 和 matTooltipHideDelay 指令来设置。单位是毫秒。

html 复制代码
<button mat-button [matTooltip]="'这是 Tooltip 文本'" [matTooltipShowDelay]="1000" [matTooltipHideDelay]="500">悬停我</button>

5. 设置 Tooltip 内容

Tooltip 的内容可以通过 [matTooltip] 指令来设置,它可以是一个字符串或者是一个模板引用。

html 复制代码
<!-- 字符串内容 -->
<button mat-button [matTooltip]="'这是 Tooltip 文本'">悬停我</button>

6. 动态控制 Tooltip 的显示和隐藏

你还可以通过属性绑定来动态控制 Tooltip 的显示和隐藏:

html 复制代码
<button mat-button [matTooltip]="shouldShowTooltip ? 'Tooltip 显示' : ''" [matTooltipDisabled]="!shouldShowTooltip">悬停我</button>

在你的组件类中,你可以控制 shouldShowTooltip 的值来显示或隐藏 Tooltip。

或者使用 #tooltip 这个 ref:

html 复制代码
<div>
  <span> Click the following buttons to... </span>
  <button mat-button
          (click)="tooltip.show()"
          aria-label="Show tooltip on the button at the end of this section"
          class="example-action-button">
    show
  </button>
  <button mat-button
          (click)="tooltip.hide()"
          aria-label="Hide tooltip on the button at the end of this section"
          class="example-action-button">
    hide
  </button>
  <button mat-button
          (click)="tooltip.toggle()"
          aria-label="Show/Hide tooltip on the button at the end of this section"
          class="example-action-button">
    toggle show/hide
  </button>
</div>

<button mat-raised-button #tooltip="matTooltip"
        matTooltip="Info about the action"
        matTooltipPosition="right"
        aria-tooltip="Button that displays and hides a tooltip triggered by other buttons">
  Action
</button>

7. 自定义 Tooltip

除了上述基本设置外,你还可以自定义 Tooltip 的样式和行为,例如通过 CSS 来改变 Tooltip 的外观,或者通过事件监听来控制 Tooltip 的行为。

这些是 Angular Material Tooltip 组件的一些基本用法。根据你的具体需求,你可以进一步探索和定制 Tooltip 组件。

25. SnackBar

Angular Material 的 Snackbar 是一种轻量级的消息提示组件,用于向用户显示简短的消息或反馈。以下是关于如何使用 Angular Material Snackbar 的一些关键点,包括传递消息、自定义样式、延时取消、ref对象以及action事件。

1. 安装和导入

首先,确保你已经安装了 Angular Material,并在你的 Angular 项目中导入了 MatSnackBarModule。

bash 复制代码
npm install @angular/material

然后在你的模块文件中导入 MatSnackBarModule:

typescript 复制代码
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { NgModule } from '@angular/core';

@NgModule({
  imports: [
    // 其他模块
    MatSnackBarModule
  ],
  // ...
})
export class AppModule { }

2. 服务注入

在你的组件中,你需要注入 MatSnackBar 服务。

typescript 复制代码
import { MatSnackBar } from '@angular/material/snack-bar';
import { Component } from '@angular/core';

@Component({
  selector: 'app-snack-bar-example',
  template: `<button (click)="openSnackBar()">打开 Snackbar</button>`
})
export class SnackBarExampleComponent {
  constructor(public snackBar: MatSnackBar) { }
}

3. 传递消息

使用 MatSnackBar 服务的 open 方法来显示 Snackbar,并传递消息。

typescript 复制代码
openSnackBar() {
  this.snackBar.open('这是一条消息', '关闭', {
    duration: 2000, // 持续时间
  });
}

4. 自定义样式

你可以通过 CSS 来自定义 Snackbar 的样式。

css 复制代码
/* app.component.css */
.custom-snack-bar-class {
  background-color: #4caf50; /* 绿色背景 */
  color: white; /* 白色文字 */
}

然后在调用 open 方法时,指定样式类:

typescript 复制代码
openSnackBar() {
  this.snackBar.open('这是一条自定义样式的消息', '关闭', {
    panelClass: ['custom-snack-bar-class'], // 自定义样式类
    duration: 2000,
  });
}

5. 延时取消

可以通过 duration 选项来设置 Snackbar 的持续时间,单位为毫秒。如果设置为 0,则 Snackbar 将不会自动消失。

typescript 复制代码
openSnackBar() {
  this.snackBar.open('这条消息将在 2 秒后消失', '关闭', {
    duration: 2000,
  });
}

6. ref对象

open 方法返回一个 MatSnackBarRef 对象,你可以通过这个对象来控制 Snackbar 的行为。

typescript 复制代码
openSnackBar() {
  const snackBarRef = this.snackBar.open('这条消息可以被手动关闭', '关闭', {
    duration: 0, // 不自动消失
  });

  // 手动关闭 Snackbar
  snackBarRef.afterDismissed().subscribe(() => {
    console.log('Snackbar 已关闭');
  });
}

7. action事件

你可以为 Snackbar 添加一个操作按钮,并监听点击事件。

typescript 复制代码
openSnackBar() {
  const snackBarRef = this.snackBar.open('这条消息有一个操作按钮', '撤销', {
    duration: 2000,
  });

  snackBarRef.onAction().subscribe(() => {
    console.log('操作按钮被点击');
  });
}

8. 配置

你还可以通过全局配置来设置 Snackbar 的默认行为。

typescript 复制代码
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class GlobalSnackBarService {
  constructor(private snackBar: MatSnackBar) {
    const defaultConfig: MatSnackBarConfig<any> = {
      duration: 2500,
      horizontalPosition: 'right',
      verticalPosition: 'bottom',
    };

    // this.snackBar.setDefaultConfig(defaultConfig);
  }

  openSnackBar(message: string, action: string = '') {
    this.snackBar.open(message, action, {
      panelClass: ['custom-snack-bar-class'], // 可以在这里添加自定义样式类
    });
  }
}

然后在组件中使用这个服务:

typescript 复制代码
constructor(private globalSnackBarService: GlobalSnackBarService) { }

openSnackBar() {
  this.globalSnackBarService.openSnackBar('这是一条全局配置的 Snackbar 消息');
}

以上就是 Angular Material Snackbar 组件的一些基本用法和配置选项。根据你的具体需求,你可以进一步探索和定制 Snackbar 组件。

26. Dialog

Angular Material 的 Dialog 组件用于创建模态对话框,可以用于显示重要的信息、表单、或者其他交互元素。以下是关于如何使用 Angular Material Dialog 的一些关键点,包括设置组件、展示 Dialog、设置标题、内容、底部按钮以及按钮上的回调,以及如何在打开 Dialog 时传递信息。

1. 安装和导入

首先,确保你已经安装了 Angular Material,并在你的 Angular 项目中导入了 MatDialogModule。

bash 复制代码
npm install @angular/material

然后在你的模块文件中导入 MatDialogModule:

typescript 复制代码
import { MatDialogModule } from '@angular/material/dialog';
import { NgModule } from '@angular/core';

@NgModule({
  imports: [
    // 其他模块
    MatDialogModule
  ],
  // ...
})
export class AppModule { }

2. 创建 Dialog 组件

创建一个 Angular 组件,这将作为 Dialog 的内容。

bash 复制代码
ng generate component DialogContent

编辑 dialog-content.component.ts:

typescript 复制代码
import { Component } from '@angular/core';

@Component({
  selector: 'app-dialog-content',
  template: `
    <h2 mat-dialog-title>这是标题</h2>
    <mat-dialog-content>
      <p>这是 Dialog 的内容。</p>
    </mat-dialog-content>
    <mat-dialog-actions>
      <button mat-button mat-dialog-close>取消</button>
      <button mat-button [mat-dialog-close]="true">确定</button>
    </mat-dialog-actions>
  `,
})
export class DialogContentComponent {}

3. 服务注入

在你的组件中,你需要注入 MatDialog 服务。

typescript 复制代码
import { MatDialog } from '@angular/material/dialog';
import { Component } from '@angular/core';
import { DialogContentComponent } from './dialog-content.component';

@Component({
  selector: 'app-dialog-example',
  template: `<button (click)="openDialog()">打开 Dialog</button>`
})
export class DialogExampleComponent {
  constructor(public dialog: MatDialog) { }

  openDialog() {
    const dialogRef = this.dialog.open(DialogContentComponent, {
      width: '250px',
      // 其他配置
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('Dialog 的结果:', result);
    });
  }
}

4. 设置组件的标题、内容、底部按钮

在 Dialog 组件的模板中,你已经可以设置标题 <h2 mat-dialog-title>,内容 <mat-dialog-content>,以及底部按钮 <mat-dialog-actions>。

5. 按钮上的回调

在 Dialog 组件中,你可以通过 mat-dialog-close 属性来设置按钮的回调。当按钮被点击时,Dialog 将关闭,并返回一个值。

html 复制代码
<!-- 在 Dialog 组件模板中 -->
<button mat-button (click)="closeDialog('取消')">取消</button>
<button mat-button (click)="closeDialog(true)">确定</button>

在 Dialog 组件的 TypeScript 文件中:

typescript 复制代码
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

export class DialogContentComponent {
  constructor(
    public dialogRef: MatDialogRef<DialogContentComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any) {}

  closeDialog(result: any): void {
    this.dialogRef.close(result);
  }
}

6. 打开的时候往其中传递信息

你可以通过 data 属性在打开 Dialog 时传递信息。

typescript 复制代码
openDialog() {
  const dialogRef = this.dialog.open(DialogContentComponent, {
    width: '250px',
    data: { message: '这是传递给 Dialog 的信息' }
  });

  dialogRef.afterClosed().subscribe(result => {
    console.log('Dialog 的结果:', result);
  });
}

在 Dialog 组件中接收传递的信息:

typescript 复制代码
export class DialogContentComponent {
  constructor(
    public dialogRef: MatDialogRef<DialogContentComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any) {}

  ngOnInit() {
    console.log('传递给 Dialog 的信息:', this.data.message);
  }

  // ...
}

以上就是 Angular Material Dialog 组件的基本用法,包括设置组件、展示 Dialog、设置标题、内容、底部按钮以及按钮上的回调,以及如何在打开 Dialog 时传递信息。根据你的具体需求,你可以进一步探索和定制 Dialog 组件。

27. HammerJS

和 Angular Material 相关的一个库是 HammerJS. Hammer.js 是一个开源的 JavaScript 库,它提供了对触摸手势的识别和处理功能。这个库允许开发者为他们的网页和移动应用添加多点触控手势,例如平移(pan)、缩放(pinch)、旋转(rotate)、滑动(swipe)等。

以下是一些关于 Hammer.js 的关键点:

兼容性

Hammer.js 旨在兼容各种设备,包括手机、平板和桌面设备。它支持现代浏览器和旧版浏览器,如 Internet Explorer 10+。

手势识别

Hammer.js 可以识别多种手势,包括但不限于:

  • 拖拽(drag)
  • 缩放(pinch)
  • 旋转(rotate)
  • 滑动(swipe)
  • 长按(press)
  • 轻触(tap)

多点触控

Hammer.js 支持多点触控手势,这意味着它可以同时处理多个触摸点,这对于实现缩放和旋转等手势非常有用。

链式手势

Hammer.js 允许你创建手势链,这意味着你可以将多个手势组合在一起,以创建更复杂的交互。

快速和轻量

Hammer.js 被设计为快速和轻量级,这意味着它不会显著影响你的网页或应用的性能。

使用示例

以下是如何在网页中使用 Hammer.js 的一个基本示例:

  1. 首先,你需要在你的 HTML 文件中包含 Hammer.js 库:
html 复制代码
<script src="path/to/hammer.min.js"></script>
  1. 然后,你可以创建一个 Hammer 实例,并将其附加到一个 DOM 元素上:
javascript 复制代码
var myElement = document.getElementById('myElement');
var mc = new Hammer(myElement);
  1. 接下来,你可以添加手势监听器:
javascript 复制代码
mc.on('swipeleft', function(event) {
  console.log('Swipe left detected');
});
  1. 你还可以通过 recognizers 选项来配置手势:
javascript 复制代码
var options = {
  recognizers: [
    [Hammer.Pan, { direction: Hammer.DIRECTION_HORIZONTAL }],
    [Hammer.Rotate]
  ]
};
var mcWithOptions = new Hammer(myElement, options);

社区和维护

Hammer.js 有一个活跃的社区,并且得到了持续的维护和更新。

替代品

尽管 Hammer.js 是一个流行的手势库,但还有其他一些库也提供了类似的功能,如 FastClick、Touchy、Swipe.js 等。

Hammer.js 是构建交互式触摸界面的强大工具,它的灵活性和易用性使其成为许多前端开发者的首选。

相关推荐
starrysky81017 天前
明明在赋值前读取,为什么还报 UnboundLocalError?——从 CPython 符号表拆解函数级作用域
angular.js
starrysky81017 天前
只填了个模型地址,5 秒就被接管——Open WebUI 攻击链拆解与「被拒 CVE」的坑
angular.js
大雄很用心25 天前
package.json 中的 dependencies 是否都会被下载?|Angular 回归笔记 02
angular.js
starrysky81025 天前
同一个 submit(),两条报错——ThreadPoolExecutor 在解释器退出时的竞态(附 4 组可复现实验)
angular.js
starrysky81025 天前
30 个 CPU 全在内核态,只回收了 32 个页——per-memcg 内存回收的 mmap_lock 活锁
angular.js
starrysky8101 个月前
一个 NameError 掩盖了真根因:IPython 补全在 Django shell 里二次崩溃——从 jedi 版本错位查到 CPython LOAD_GLOBAL
angular.js
starrysky8101 个月前
SQL 注入 + msgpack 反序列化 = RCE:LangGraph Checkpointer 三洞连爆——Agent 的记忆层就是攻击面
angular.js
starrysky8101 个月前
NVD 9.8、官方 7.5:Redis TLS use-after-free 的评分之争——tlsProcessPendingData 悬指针踩空全解析
angular.js
巴勒个啦1 个月前
2026 年 CSS 选型真相:我用 Tailwind v4 + 原生新特性重构了一个组件库
前端·angular.js
starrysky8102 个月前
服务全绿、队列却 15 天没人消费?redis-py 8.0 默认切 RESP3 的阻塞命令坑
angular.js