fix: two clicks are needed to chenge the theme for the first time

This commit is contained in:
Doyoung
2025-10-24 19:01:01 +08:00
parent 2da1af14c5
commit 3d0478f477
2 changed files with 58 additions and 20 deletions

View File

@@ -1,33 +1,71 @@
import {useSettingStore} from "@/stores/setting.ts";
type Theme = "light" | "dark";
// 获取系统主题
function getSystemTheme(): Theme {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
} else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
return 'light';
}
return 'light'; // 默认浅色模式
}
// 交换主题名称
function swapTheme(theme: Theme): Theme {
return theme === 'light' ? 'dark' : 'light'
}
// 监听系统主题变化
function listenToSystemThemeChange(call: (theme: Theme) => void) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
if (e.matches) {
// console.log('系统已切换到深色模式');
call('dark');
}
});
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', e => {
if (e.matches) {
// console.log('系统已切换到浅色模式');
call('light');
}
});
}
export default function useTheme() {
const settingStore = useSettingStore()
// // 查询当前系统主题颜色
// const match: MediaQueryList = window.matchMedia("(prefers-color-scheme: dark)")
// // 监听系统主题变
// match.addEventListener('change', followSystem)
//
// function followSystem() {
// document.documentElement.className = match.matches ? 'dark' : 'light'
// }
// 开启监听系统主题变更,后期可以通过用户配置来决定是否开启
listenToSystemThemeChange((theme: Theme) => {
// 如果系统主题变更后和当前的主题一致,则不需要再重新切换
if(settingStore.theme === theme){
return;
}
settingStore.theme = theme;
setTheme(theme);
})
function toggleTheme() {
if (settingStore.theme === 'auto') {
settingStore.theme = 'light'
} else {
settingStore.theme = settingStore.theme === 'light' ? 'dark' : 'light'
}
setTheme(settingStore.theme)
// auto模式下默认是使用系统主题切换时应该使用当前系统主题为基础进行切换
settingStore.theme = swapTheme(settingStore.theme === 'auto' ? getSystemTheme() : settingStore.theme as Theme);
setTheme(settingStore.theme);
}
function setTheme(val) {
document.documentElement.className = val
function setTheme(val:string) {
// auto模式下则通过查询系统主题来设置主题名称
document.documentElement.className = val === 'auto' ? getSystemTheme() : val;
}
// 获取当前具体的主题名称
function getTheme():Theme{
// auto模式下则通过查询系统主题来获取当前具体的主题名称
return settingStore.theme === 'auto' ? getSystemTheme() : settingStore.theme as Theme;
}
return {
toggleTheme,
setTheme
setTheme,
getTheme
}
}