Material使用06 自定义主题、黑夜模式\白天模式切换
需求:
1 不使用materil依赖内建的主题,使用自己创建的主题
2 利用自己创建的主题实现白天模式和黑夜模式
1 自定义主题
1.1 创建自定义主题文件 them.scss
// 引入material自定义主题支持 @import '~@angular/material/theming'; // 引入material公用的主题风格 @include mat-core(); // 自定义颜色 $my-app-primary: mat-palette($mat-blue); $my-app-accent: mat-palette($mat-teal, A200, A100, A400); $my-app-warn: mat-palette($mat-red); // 利用自定义颜色组装自定义主题 $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); // 设置自定义主题,使其生效 @include angular-material-theme($my-app-theme);
1.1.1 引入material主题支持和material公用的主题风格
// 引入material自定义主题支持 @import '~@angular/material/theming'; // 引入material公用的主题风格 @include mat-core();
1.1.2 根据material公用的主题风格设定自己的主题颜色
// 自定义颜色 $my-app-primary: mat-palette($mat-blue); // 主色 $my-app-accent: mat-palette($mat-teal, A200, A100, A400); // 副色 $my-app-warn: mat-palette($mat-red); // 警告色
代码解释01: $my-app-primary就是一个自定义的变量
代码解释02: $mat-blue表示使用material主题风格中的blue这种颜色
代码解释03: $my-app-primary: mat-palette($mat-blue); 表示通过material主题风格的函数将material主题风格中的blue颜色赋值给$my-app-primary变量
技巧01:如何查看material的主题风格中提供了哪些颜色 -> 点击前往
1.1.3 利用自己的主题颜色组成自定义主题
// 利用自定义颜色组装自定义主题 $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);
1.1.4 设置主题颜色使其生效
// 设置自定义主题,使其生效 @include angular-material-theme($my-app-theme);
1.2 在全局样式文件中引入自定义的主题文件them.scss
技巧01:需要将默认引入的materi内建主题注释掉
/* You can add global styles to this file, and also import other style files */ // @import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; // 导入material的内建主体 @import 'theme.scss'; html, body, app-root, md-sidenav-container, .site { width: 100%; height: 100%; margin: 0; } .site { display: flex; flex-direction: column; } header { // background-color: skyblue; } main { flex: 1; } footer { // background-color: skyblue; } .fill-remaining-space { // flex项目自动填充多余空间 flex: 1 1 auto; } .full-width { width: 100%; }
1.3 效果如下
2 利用多主题实现多模式
2.1 添加黑夜主题
// 引入material自定义主题支持 @import '~@angular/material/theming'; // 引入material公用的主题风格 @include mat-core(); // 自定义颜色 $my-app-primary: mat-palette($mat-green); $my-app-accent: mat-palette($mat-amber, A200, A100, A400); $my-app-warn: mat-palette($mat-red); // 利用自定义颜色组装自定义主题 $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn); // 设置自定义主题,使其生效 @include angular-material-theme($my-app-theme); // 自定义颜色 $my-dark-primary: mat-palette($mat-blue-grey); // 主色 $my-dark-accent: mat-palette($mat-amber, A200, A100, A400); // 副色 $my-dark-warn: mat-palette($mat-deep-orange); // 警告色 // 利用自定义颜色组装自定义主题 $my-dark-theme: mat-dark-theme($my-dark-primary, $my-dark-accent, $my-dark-warn); // 设置自定义主题,使其生效 .myapp-dark-theme { @include angular-material-theme($my-dark-theme); }
技巧01:将黑夜主题放在一个class类中进行引入,当这个类被激活时就表示开启黑夜模式
技巧02:主题只能对material相关的组件生效,其余的组件不会生效;我们可以将最外层组件生效myapp-dark-theme样式时添加最外层组件的背景颜色
<md-sidenav-container [class.myapp-dark-theme]="darkTheme"> <md-sidenav #sidebar> <app-sidebar></app-sidebar> </md-sidenav> <div class="site"> <header> <app-header (toggle)="sidebar.toggle()" (taggleDarkTheme)="switchTheme($event)"></app-header> </header> <main> <router-outlet></router-outlet> </main> <footer> <app-footer></app-footer> </footer> </div> </md-sidenav-container>
md-sidenav-container.myapp-dark-theme { background-color: black; } md-sidenav { width: 200px; }
2.2 在页眉组件添加一个按钮用于开启或者关闭黑夜模式
2.2.1 在共享模块中引入MdSlideToggleModule
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MdSidenavModule, MdToolbarModule, MdIconModule, MdButtonModule, MdIconRegistry, MdCardModule, MdInputModule, MdListModule, MdSlideToggleModule } from '@angular/material'; import { HttpModule } from '@angular/http'; @NgModule({ imports: [ CommonModule, HttpModule, MdSidenavModule, MdToolbarModule, MdIconModule, MdButtonModule, MdCardModule, MdInputModule, MdListModule, MdSlideToggleModule ], declarations: [], exports: [ CommonModule, MdSidenavModule, MdToolbarModule, MdIconModule, MdButtonModule, HttpModule, MdCardModule, MdInputModule, MdListModule, MdSlideToggleModule ] }) export class SharedModule { }
2.2.2 在组件中使用MdSlideToggleModule提供的md-slide-toggle组件
<md-toolbar color="primary"> <button md-icon-button (click)="openSidebar()"> <md-icon>menu</md-icon> </button> <span>企业协作平台</span> <!-- <md-icon>accessibility</md-icon> <md-icon svgIcon="header"></md-icon> --> <span class='fill-remaining-space'></span> <md-slide-toggle (change)='onChange($event.checked)'>黑夜模式</md-slide-toggle> </md-toolbar>
代码解释01:<span class='fill-remaining-space'></span>的主要作用是撑满剩余的空间
代码解释02:(change)='onChange($event.checked)' 的作用是当md-slide-toggle组件发生变化时执行相应的方法,参数md-slide-toggle的当前值
技巧01:md-slide-toggle官方文档 -> 点击前往
2.2.3 在使用md-slide-toggle的组件编写一个输出变量
当md-slide-toggle组件的值发生变化时就将变化后的值发送给使用md-slide-toggle这个组件的父组件
import { Component, OnInit, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.scss'] }) export class HeaderComponent implements OnInit { @Output() toggle = new EventEmitter<void>(); @Output() toggleDarkTheme = new EventEmitter<boolean>(); constructor() { } ngOnInit() { } openSidebar() { this.toggle.emit(); } onChange(eventValue: boolean) { // console.log('是否黑夜模式:' + eventValue); this.toggleDarkTheme.emit(eventValue); } }
2.2.4 在父组件中监听使用md-slide-toggle的那个组件触发的事件
<md-sidenav-container [class.myapp-dark-theme]="darkTheme"> <md-sidenav #sidenav mode="push"> <app-sidenav></app-sidenav> </md-sidenav> <div class="site"> <header> <app-header (toggle)="sidenav.toggle()" (toggleDarkTheme)="switchTheme($event)"></app-header> </header> <main> <router-outlet></router-outlet> </main> <footer> <app-footer></app-footer> </footer> </div> </md-sidenav-container>
代码解释01:<app-header (toggle)="sidenav.toggle()" (toggleDarkTheme)="switchTheme($event)"></app-header> 当app-header组件触发toggleDarkTheme会引发使用app-haeder组件的父组件触发switchTheme方法,并将app-header组件发出的参数接收到作为switchTheme方法的参数
2.2.5 在父组件中编写switchTheme方法
该方法根据接收到的参数真假来判断是否开启黑夜模式对应的class类
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { darkTheme = false; switchTheme(dark) { this.darkTheme = dark; // alert(this.darkTheme); } }
2.3 效果图如下
2.3.1 白天模式
2.3.2 黑夜模式