效果圖:
框架版本:
第一種方案:使用scss預處理器。思路是通過點擊事件,控制body上自定義屬性的值,利用scss @mixin指令實現切換CSS樣式。具體代碼實現如下
-
在assests文件夾下新建base.scss(主題參數變量)和mixin.scss兩個樣式文件
base.scss:$background-color-blue: #1dd3f3; $background-color-black: #0c0b0b;
mixin.scss:
@import './base.scss'; @mixin bg_color() { :host-context([data-theme='blue']) & { background-color: $background-color-blue; } :host-context([data-theme='black']) & { background-color: $background-color-black; } }
-
全局styles.scss樣式文件引入mixin.scss文件
@import './assets/scss/mixin.scss';
-
在app.component.scss中應用定義在mixin.scss文件中的樣式
@import '../styles.scss'; .toolbar_scss{ @include bg_color }
-
修改app.component.html文件(使用mat-menu標籤需要安裝material組件庫,執行ng add @angular/material命令後,在app.module.ts中引入MatIconModule, MatMenuModule即可)
<div class="spacer"> <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" style="margin-top: 68px"> <button mat-menu-item (click)="changeTheme('blue')"> <mat-icon>dialpad</mat-icon> <span>藍色</span> </button> <button mat-menu-item (click)="changeTheme('black')"> <mat-icon>voicemail</mat-icon> <span>黑色</span> </button> </mat-menu> </div>
-
app.component.ts文件通過點擊事件控制body上自定義屬性的值,並存入localStorage中
export class AppComponent { title = 'angular-ui'; themeUI: string; ngOnInit() { this.setTheme(); } changeTheme(theme: string) { const body = document.getElementsByTagName('body')[0]; const currentTheme = body.getAttribute(`data-theme`); if (currentTheme !== theme) { body.setAttribute('data-theme', theme); this.saveTheme(theme) } } saveTheme(theme: string) { localStorage.setItem(`theme`, theme); } setTheme() { this.themeUI = localStorage.getItem('theme') || 'blue' const body = document.getElementsByTagName('body')[0]; body.setAttribute('data-theme', this.themeUI); } }
總結:@mixin bg_color()生效原理利用了:host-context() 僞類選擇器。它類似 :host() 形式使用。它在當前組件宿主元素的祖先節點中查找 CSS 類, 直到文檔的根節點爲止。
參考:https://segmentfault.com/a/11...