如何使用Angular material 2制作响应式导航栏?

37

我正在尝试使用Angular Material 2创建一个导航栏,使其在小屏幕设备(如移动设备和平板电脑)上折叠。

我只能找到md-button,但找不到 Angular Material 中的 md-menu-bar

8个回答

54

这是我使用 Angular2+ Material 2 和 flex-layout 在 angular-cli 应用中构建响应式 nav-bar 所使用的内容。

(请访问安装 Angular Material 和 Angular CDK)

1)安装 flex-layout

npm install @angular/flex-layout -save

2)在您的app.module.ts中包含flex-layout

import {FlexLayoutModule} from "@angular/flex-layout";

3) 导入

imports: [
 BrowserModule,
 FormsModule,
 HttpModule,
 RoutingModule,
 FlexLayoutModule,
MyOwnCustomMaterialModule // Please visit the link above "Install Angular Material and Angular CDK", and check (Step 3: Import the component modules).
],

app.component.html

<mat-toolbar color="primary">

    <button mat-button routerLink="/">
    <mat-icon>home</mat-icon> 
        {{title}}</button>

    <!-- This fills the remaining space of the current row -->
    <span class="fill-remaining-space"></span>
    <div fxLayout="row" fxShow="false" fxShow.gt-sm>
        <button mat-button routerLink="/products">Products</button>
        <button mat-button routerLink="/dashboard">Dashboard</button>
    </div>
    <button mat-button [mat-menu-trigger-for]="menu" fxHide="false" fxHide.gt-sm>
     <mat-icon>menu</mat-icon>
    </button>

</mat-toolbar>
<mat-menu x-position="before" #menu="matMenu">
    <button mat-menu-item routerLink="/products">Products</button>
    <button mat-menu-item routerLink="/dashboard">Dashboard</button>
    <!--<button mat-menu-item>Help</button>-->
</mat-menu>

app.component.css

.fill-remaining-space {
   /*This fills the remaining space, by using flexbox.  
  Every toolbar row uses a flexbox row layout. */
  flex: 1 1 auto;
}

注意:测试时请调整页面大小。

请查看flex-layout文档。


非常好用。感谢关于flex-layout的提醒,我之前没有听说过它。 - David Martin
很高兴听到这个好消息 :) - user2662006
3
很棒的解决方案。只需记住FlexLayoutModule.forRoot()已被弃用,我们现在只使用FlexLayoutModule。 - Cengkuru Michael
1
想给一个小建议:在折叠时显示的菜单中,使用md-menu-item可能更合适。 - Deniss M.
1
angular-material 更改了大多数组件的名称。此代码片段在 angular-material 5.0.2 中不起作用。 - Anup
2
@Ruben 不错的问题.. 我也在想,Angular 应该首先推出一个简单的响应式菜单,对吧? - Melroy van den Berg

18

以下是我的最喜欢的在Angular中创建响应式导航栏的方法。如果您使用Angular 6,请确保使用版本6.1+。
Stackblitz上的工作示例:https://stackblitz.com/edit/angular-v6xwte

在较小屏幕上的示例: 小屏幕上的工具栏

在较大屏幕上的示例: 大屏幕上的工具栏

以下是详细步骤:

1)安装必要的软件包。在终端中输入以下命令:

npm install --save @angular/material @angular/cdk @angular/animations

npm install @angular/flex-layout --save

2) 在你的 app.module.ts 中导入必要的模块。

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';
import {
  MatIconModule, MatButtonModule, MatSidenavModule, MatToolbarModule
} from '@angular/material';

记得将这些模块添加到下面的导入数组中。

3) 在你的index.html中添加Material Icons链接
链接必须在任何Angular内容之前。

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

4) 在你的 styles.css 文件中添加 Angular 主题并将边距设置为 0%

@import "~@angular/material/prebuilt-themes/indigo-pink.css";
body{
    margin: 0%;
}

5) 在您的 app.component.html 文件中添加工具栏HTML代码。

<div style="height: 100vh;"> 
<mat-toolbar color="primary">
    <div fxShow="true" fxHide.gt-sm="true">
      <button mat-icon-button (click)="sidenav.toggle()">
        <mat-icon>menu</mat-icon>
      </button>
    </div>
    <a mat-button class="companyName" routerLink="/">
      <span>Site name</span>
    </a>
    <span class="example-spacer"></span>
    <div fxShow="true" fxHide.lt-md="true">
      <a mat-button routerLink="/about-us">About us</a>
      <a mat-button routerLink="/prices">Prices</a>
      <a mat-button routerLink="/start-page">Start page</a>
      <a mat-button routerLink="/offer">Offer</a>
      <a mat-button routerLink="/contact">Contact</a>
    </div>
  </mat-toolbar>
  <mat-sidenav-container fxFlexFill class="example-container">
    <mat-sidenav color="primary" #sidenav fxLayout="column" mode="over" opened="false" fxHide.gt-sm="true">
      <div fxLayout="column">
        <a mat-button routerLink="/about-us">About us</a>
        <a mat-button routerLink="/prices">Prices</a>
        <a mat-button routerLink="/start-page">Start page</a>
        <a mat-button routerLink="/offer">Offer</a>
        <a mat-button routerLink="/contact">Contact</a>
      </div>
    </mat-sidenav>
    <mat-sidenav-content fxFlexFill>
      Awesome content
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>

6) 在你的 app.component.css 文件中为工具栏设置样式。

.companyName{
    font-size: 150%;
}
div {
    overflow: inherit;
}
a{
    text-decoration: none;
    font-size: 110%;
    white-space: normal;
}
button{
    font-size: 110%;
    min-width: min-content;
}
.example-icon {
    padding: 0 14px;
  }

  .example-spacer {
    flex: 1 1 auto;
  }
  .mat-sidenav-content{
      font-size: 200%;
      text-align: center;
  }

目前菜单项只是普通的锚点元素。但你可以按照自己的喜好进行样式设计,例如使用树形结构 https://material.angular.io/components/tree/overview 或者菜单 https://material.angular.io/components/menu/overview。 - Tomasz Chudzik
这是我找到的最好、最简洁的答案。 - user796446

17

使用 Angular CLI 的 schematics 是使用 Material 创建响应式导航栏的最简单方法。

(如果运行 ng add @angular/material 时出现“无法解析集合“@angular/material””,请参见 这里)

然后使用生成的组件 <app-my-nav></app-my-nav>,将上述标记添加到您的主组件中。

在桌面电脑上查看响应式视图: Responsive view on Desktop PC

低分辨率时的响应式折叠菜单: Responsive collapsed menu with low resolution

这篇文章最初出现在 Angular 的博客 上。


这个使用 Angular CLI 的文档在哪里可以找到? - ctilley79

4

这是我的初步尝试,使用新的组件名称来实现抽屉式工具栏的修改,与angular-material 5.0.2一起使用。

待完成任务:需要修复所有标题链接的CSS。菜单图标应该是透明的。

https://responsivematerial2.stackblitz.io/

.mat-sidenav-container {
  background: rgba(0, 0, 0, 0.08);
}

.blank-grow {
  flex: 1 1 auto;
}
<mat-sidenav-container fullscreen>
  <mat-sidenav #sidenav>
    <mat-nav-list>
      <a mat-list-item>
        <mat-icon mat-list-icon>home</mat-icon>
        <span mat-line>home</span>
      </a>

      <a mat-list-item>
        <mat-icon mat-list-icon>backup</mat-icon>
        <span mat-line>Backup</span>
      </a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-toolbar color="primary">
    <button mat-icon-button (click)="sidenav.open()" fxHide="false" fxHide.gt-sm>
      <mat-icon>menu</mat-icon>
    </button>
    <span> Big Header</span>
    <span class="blank-grow"></span>
    <div fxLayout="row" fxShow="false" fxShow.gt-sm>
      <a>
        <mat-icon mat-list-icon>home</mat-icon>
        <span mat-line>home</span>
      </a>

      <a>
        <mat-icon mat-list-icon>backup</mat-icon>
        <span mat-line>Backup</span>
      </a>
    </div>
  </mat-toolbar>
</mat-sidenav-container>


谢谢!基于 https://stackblitz.com/angular/yaldykdbaln?file=app%2Fsidenav-responsive-example.html 吗?还是不基于? - Melroy van den Berg

4

4
我已经对 user2662006 的答案进行了一些修正和代码优化。请注意,我的StackOverflow积分目前太低,无法获得提交评论甚至编辑的特权。
1) 安装 Angular Material 和 Angular CDK 2) 安装 flex-layout
npm install @angular/flex-layout -save

3) 在您的 app.module.ts 中引入 flex-layout

import {FlexLayoutModule} from "@angular/flex-layout";

4) 导入相关的材料和 Flex 模块

imports: [
 ...,
 FlexLayoutModule,
 MatToolbarModule,
 MatIconModule,
 MatMenuModule,
 MatButtonModule,
],

app.component.html

<mat-toolbar color="primary">
    <button mat-button routerLink="/">
        <mat-icon>home</mat-icon> 
        {{title}}
    </button>

    <span class="fill-remaining-space"></span>

    <div fxLayout="row" fxHide fxShow.gt-sm>
        <button mat-button routerLink="/products">Products</button>
        <button mat-button routerLink="/dashboard">Dashboard</button>
    </div>
    <button mat-button [mat-menu-trigger-for]="menu" fxShow fxHide.gt-sm>
     <mat-icon>menu</mat-icon>
    </button>

</mat-toolbar>
<mat-menu x-position="before" #menu>
    <button mat-menu-item routerLink="/products">Products</button>
    <button mat-menu-item routerLink="/dashboard">Dashboard</button>
</mat-menu>

app.component.css

.fill-remaining-space {
   /*This fills the remaining space, by using flexbox.  
  Every toolbar row uses a flexbox row layout. */
  flex: 1 1 auto;
}

注意事项:


如何添加嵌套菜单? - SK.

3

我的演示文稿,创建用户喜爱的企业级UI界面,涵盖了一些Angular Material的模式。StackBlitz示例的链接在演讲者注释中。

响应式按钮栏与溢出菜单: 可以放置在或下方TopNav中。 https://stackblitz.com/edit/material-responsive-button-bar?file=app%2Fbutton-bar%2Fbutton-bar.component.ts

动态嵌套TopNav菜单: 请注意,此菜单不是完全可访问的。需要更多的工作来完全支持良好的可访问性体验。 https://stackblitz.com/edit/dynamic-nested-topnav-menu?file=app/app.component.ts

动态嵌套SideNav菜单: 如果您使用变换模式将您的TopNav在移动设备上切换到SideNav,这将展示如何构建动态的SideNav菜单。 https://stackblitz.com/edit/dynamic-nested-sidenav-menu?file=app%2Fapp.component.html


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接