You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular v16中如何运行时切换Material预定义主题?

Angular 16 运行时切换Material预定义主题的实现方法

步骤1:将预定义主题包裹到独立CSS类中

在项目根目录的styles.scss文件中,把每个Material预定义主题的样式嵌套在专属类选择器下,避免样式冲突:

// Indigo Pink 主题
.indigo-pink-theme {
  @import '@angular/material/prebuilt-themes/indigo-pink.css';
}

// Pink Bluegrey 主题
.pink-bluegrey-theme {
  @import '@angular/material/prebuilt-themes/pink-bluegrey.css';
}

// Purple Green 主题
.purple-green-theme {
  @import '@angular/material/prebuilt-themes/purple-green.css';
}

// Deep Purple Amber 主题
.deeppurple-amber-theme {
  @import '@angular/material/prebuilt-themes/deeppurple-amber.css';
}

步骤2:设置默认主题类

打开src/index.html,给<body>标签添加默认的主题类:

<body class="indigo-pink-theme">
  <app-root></app-root>
</body>

步骤3:实现主题切换组件

创建一个切换组件(比如theme-switcher.component.ts),通过修改<body>的类来切换主题,同时支持本地存储保存用户选择:

import { Component, Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Component({
  selector: 'app-theme-switcher',
  template: `
    <mat-button-toggle-group [(ngModel)]="selectedTheme" (change)="switchTheme()">
      <mat-button-toggle value="indigo-pink-theme">Indigo Pink</mat-button-toggle>
      <mat-button-toggle value="pink-bluegrey-theme">Pink Bluegrey</mat-button-toggle>
      <mat-button-toggle value="purple-green-theme">Purple Green</mat-button-toggle>
      <mat-button-toggle value="deeppurple-amber-theme">Deep Purple Amber</mat-button-toggle>
    </mat-button-toggle-group>
  `
})
export class ThemeSwitcherComponent {
  selectedTheme = 'indigo-pink-theme';

  constructor(
    private renderer: Renderer2,
    @Inject(DOCUMENT) private document: Document
  ) {
    // 从本地存储恢复上次选择的主题
    const savedTheme = localStorage.getItem('selectedTheme');
    if (savedTheme) {
      this.selectedTheme = savedTheme;
      this.updateBodyThemeClass();
    }
  }

  switchTheme(): void {
    this.updateBodyThemeClass();
    localStorage.setItem('selectedTheme', this.selectedTheme);
  }

  private updateBodyThemeClass(): void {
    // 移除旧的主题类
    const oldTheme = Array.from(this.document.body.classList).find(cls => cls.endsWith('-theme'));
    if (oldTheme) {
      this.renderer.removeClass(this.document.body, oldTheme);
    }
    // 添加新的主题类
    this.renderer.addClass(this.document.body, this.selectedTheme);
  }
}

步骤4:导入必要模块

在你的功能模块或根模块(比如app.module.ts)中,导入Material按钮切换模块和表单模块:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { ThemeSwitcherComponent } from './theme-switcher/theme-switcher.component';

@NgModule({
  declarations: [
    AppComponent,
    ThemeSwitcherComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatButtonToggleModule,
    FormsModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

注意事项

  • 必须导入BrowserAnimationsModule,否则Material组件无法正常工作。
  • 嵌套主题到类中的目的是避免多个主题样式互相覆盖,只有当根元素拥有对应类时,该主题样式才会生效。
  • 本地存储逻辑可选,用于在页面刷新后保留用户的主题偏好。

内容的提问来源于stack exchange,提问作者vitaly-t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:07:53