Material使用11 核心模块和共享模块、 如何使用@angular/material
1 创建项目
1.1 版本说明
1.2 创建模块
1.2.1 核心模块
该模块只加载一次,主要存放一些核心的组件及服务
ng g m core
1.2.1.1 创建一些核心组件
页眉组件:header
ng g c core/header --module core
内容组件:main
ng g c core/main --module core
页脚组件:footer
ng g c core/footer --module core
1.2.1.2 如何让核心模块只加载一次
在核心模块对应类中的构造器中增添如下代码
constructor( @Optional() @SkipSelf() parent: CoreModule) { if (parent) { throw new Error('核心模块已经加载了,请勿重复加载'); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { NgModule, SkipSelf, Optional } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HeaderComponent } from './header/header.component'; import { MainComponent } from './main/main.component'; import { FooterComponent } from './footer/footer.component'; @NgModule({ imports: [ CommonModule ], declarations: [ HeaderComponent, MainComponent, FooterComponent ], exports: [ HeaderComponent, MainComponent, FooterComponent ] }) export class CoreModule { constructor( @Optional() @SkipSelf() parent: CoreModule) { if (parent) { throw new Error('核心模块已经加载了,请勿重复加载'); } } }
代码解释:
@SkipSelf() -> 该注解的作用是告诉应用在进行依赖注入时要排除自身(即:不想从当前元素获取依赖),这样注入器就会从一个在自己 上一级 的组件开始搜索一个CoreModule依赖;如果不添加时就会出现解析错误:
@Optional() -> 该注解的作用是保证依赖找不到时报错,当CoreModule不存在时就进行了依赖注入就会报错;当无法确保依赖是否存在的情况下,而又为了避免抛出找不到依赖的错误情况,可以使用@Optional()注解,这样该依赖是可选的,此处我们是为了保证都次导入核心模块时不依赖注入CoreModule;如果不添加就会出现实例找不到的错误:
1.2.2 共享模块
该模块可以多次加载,将一些公用的组件和模块放到该模块下并做导出操作
ng g m shared
1.3 构建应用大体结构
利用flex布局实现三段式布局,flex布局详解
1.3.1 模块导入
在主模块中导入核心模块和共享模块
1.3.2 重构主组件
<div class="site"> <header> <app-header></app-header> </header> <main> <app-main></app-main> </main> <footer> <app-footer></app-footer> </footer> </div>
坑01:虽然已经在主模块中导入了核心模块,但是在主模块中的所有组件只可以用核心模块中导出的东西
技巧01:在核心模块中导出主模块中需要用到的三个组件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { NgModule, SkipSelf, Optional } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HeaderComponent } from './header/header.component'; import { MainComponent } from './main/main.component'; import { FooterComponent } from './footer/footer.component'; @NgModule({ imports: [ CommonModule ], declarations: [ HeaderComponent, MainComponent, FooterComponent ], exports: [ HeaderComponent, MainComponent, FooterComponent ] }) export class CoreModule { constructor( @Optional() @SkipSelf() parent: CoreModule) { if (parent) { throw new Error('核心模块已经加载了,请勿重复加载'); } } }
1.3.3 添加全局样式
在全局样式中利用flex布局实现主组件的三段式布局
html, body, app-root, mat-sidenav-container, .site { width: 100%; height: 100%; margin: 0; } .site { display: flex; flex-direction: column; } header { background-color: skyblue; } main { background-color: grey; flex: auto; } footer { background-color: skyblue; }
1.3.4 效果展示
2 @angular/material使用
2.1 安装 material 和 cdk
@angular/cdk -> ng 对于 ui 组建的基础架构,是由 material 团队开发与维护的, 之所以会有 cdk 看样子是因为在开发 material 的时候随便抽象一个层次出来给大家用。
npm install --save @angular/material @angular/cdk
技巧01:推荐使用cnpm安装
2.2 安装 animations
一些 material 组件需要依赖 @angular/animations 来实现动画跳转
npm install --save @angular/animations
技巧01:仅仅安装 @angular/animations 是没有用的,还需要在核心模块或者是主模块中导入BrowserAnimationsModule
或者NoopAnimationsModule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { TestModule } from './test/test.module'; import { CoreModule } from './core/core.module'; import { SharedModule } from './shared/shared.module'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, BrowserAnimationsModule, CoreModule, SharedModule, TestModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
2.3 引入material内置主题
在全局演示用利用 @import 引入
@import '~_@angular_material@5.2.2@@angular/material/prebuilt-themes/deeppurple-amber.css';
2.4 手势支持
由于material是一个支持多种设备终端的组件库,为了支持一些移动端设备material组件用到了HammerJS,如果没有HammerJS就可能出现某些移动端不能正常显示
cnpm install --save hammerjs
技巧01:仅仅安装hammerjs还不行,还需要在核心模块或者主模块中引入
import 'hammerjs';
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { NgModule, SkipSelf, Optional } from '@angular/core'; import { CommonModule } from '@angular/common'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { HeaderComponent } from './header/header.component'; import { MainComponent } from './main/main.component'; import { FooterComponent } from './footer/footer.component'; import 'hammerjs'; @NgModule({ imports: [ CommonModule, BrowserAnimationsModule ], declarations: [ HeaderComponent, MainComponent, FooterComponent ], exports: [ HeaderComponent, MainComponent, FooterComponent ] }) export class CoreModule { constructor( @Optional() @SkipSelf() parent: CoreModule) { if (parent) { throw new Error('核心模块已经加载了,请勿重复加载'); } } }
3 MatSidenavModule的使用
3.1 导入MatSidenavModule
在共享模块中导入并导出MatSidenavModule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatSidenavModule } from '@angular/material'; @NgModule({ imports: [ CommonModule, MatSidenavModule ], declarations: [], exports: [ MatSidenavModule ] }) export class SharedModule { }
3.2 使用MatSidenavModule中的组件
使用MatSidenavModule中的组件实现侧边栏效果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<mat-sidenav-container> <mat-sidenav #sidenav> <p>hello boy</p> </mat-sidenav> <div class="site"> <header> <app-header></app-header> </header> <main> <button (click)="sidenav.open()">点击划出</button> <app-main></app-main> </main> <footer> <app-footer></app-footer> </footer> </div> </mat-sidenav-container>
3.3 效果展示
3.4 官方文档