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
相关产品推荐
相关产品推荐

