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

Ionic 8 + Angular 18 如何实现暗色模式切换?

在Ionic 8 + Angular 18中实现主题切换功能

1. 调整全局样式文件(global.scss)

要实现手动切换主题,需要将原有的系统跟随式样式替换为类驱动的深色模式样式,这样可以通过操作DOM类来控制主题切换。修改你的global.scss:

// 注释/移除原有的系统跟随样式
// @import '@ionic/angular/css/palettes/dark.system.css';

// 导入基于类的深色模式样式——仅当html标签带有dark类时生效
@import '@ionic/angular/css/palettes/dark.class.css';

2. 创建主题管理服务

生成一个Angular服务来统一处理主题状态存储、系统偏好监听和主题切换逻辑:

先执行命令生成服务:

ng generate service services/theme

然后修改theme.service.ts代码:

import { Injectable, OnInit } from '@angular/core';

export type ThemeMode = 'system' | 'dark' | 'light';

@Injectable({
  providedIn: 'root'
})
export class ThemeService implements OnInit {
  private currentMode: ThemeMode = 'system';

  ngOnInit() {
    // 初始化:优先读取本地存储的用户设置,无则跟随系统
    const savedMode = localStorage.getItem('themeMode') as ThemeMode;
    if (savedMode) {
      this.currentMode = savedMode;
      this.applyTheme(savedMode);
    } else {
      this.applySystemTheme();
    }

    // 监听系统主题变化(仅在模式为system时同步)
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
      if (this.currentMode === 'system') {
        this.applySystemTheme();
      }
    });
  }

  // 切换主题模式
  setThemeMode(mode: ThemeMode) {
    this.currentMode = mode;
    localStorage.setItem('themeMode', mode);
    this.applyTheme(mode);
  }

  // 获取当前主题模式
  getCurrentMode(): ThemeMode {
    return this.currentMode;
  }

  // 根据模式应用主题
  private applyTheme(mode: ThemeMode) {
    const htmlEl = document.documentElement;
    htmlEl.classList.remove('dark');

    if (mode === 'dark') {
      htmlEl.classList.add('dark');
    } else if (mode === 'system') {
      this.applySystemTheme();
    }
    // light模式下直接移除dark类即可
  }

  // 应用系统偏好的主题
  private applySystemTheme() {
    const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
    const htmlEl = document.documentElement;
    isDark ? htmlEl.classList.add('dark') : htmlEl.classList.remove('dark');
  }
}

3. 添加主题切换UI

在目标页面(比如设置页)添加切换控件,这里用ion-segment做示例:

页面模板(settings.page.html)

<ion-header>
  <ion-toolbar>
    <ion-title>主题设置</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
  <ion-segment [(ngModel)]="selectedThemeMode" (ionChange)="onThemeChange()">
    <ion-segment-button value="system">
      <ion-label>跟随系统</ion-label>
    </ion-segment-button>
    <ion-segment-button value="dark">
      <ion-label>深色模式</ion-label>
    </ion-segment-button>
    <ion-segment-button value="light">
      <ion-label>浅色模式</ion-label>
    </ion-segment-button>
  </ion-segment>
</ion-content>

页面逻辑(settings.page.ts)

import { Component, OnInit } from '@angular/core';
import { ThemeService, ThemeMode } from '../services/theme.service';

@Component({
  selector: 'app-settings',
  templateUrl: './settings.page.html',
  styleUrls: ['./settings.page.scss'],
})
export class SettingsPage implements OnInit {
  selectedThemeMode: ThemeMode = 'system';

  constructor(private themeService: ThemeService) {}

  ngOnInit() {
    this.selectedThemeMode = this.themeService.getCurrentMode();
  }

  onThemeChange() {
    this.themeService.setThemeMode(this.selectedThemeMode);
  }
}

4. 关键说明

  • 本地存储会保存用户的主题偏好,下次启动APP时自动恢复设置。
  • 选择「跟随系统」模式时,系统主题变化会自动同步到APP。
  • dark.class.css依赖Ionic基础样式,确保项目已正确导入Ionic全局样式。

内容的提问来源于stack exchange,提问作者Ravi Gaud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:19:54