feat: 添加深色主题支持并优化外观设置

1. 新增全局深色主题样式变量,适配明暗两种主题
2. 配置naive-ui主题切换,跟随系统或用户设置
3. 修复外观设置页面主题同步逻辑
4. 调整主布局样式,使用css变量适配主题和标题栏高度
This commit is contained in:
Yuhang Wu 2026-08-25 09:31:42 +08:00
parent 0242f14aaa
commit 3ce9735cda
4 changed files with 58 additions and 5 deletions

View File

@ -1,5 +1,9 @@
<template> <template>
<n-config-provider :locale="zhCN" :data-locale="dateZhCN"> <n-config-provider
:locale="zhCN"
:data-locale="dateZhCN"
:theme="isDark ? darkTheme : null"
>
<n-message-provider> <n-message-provider>
<n-notification-provider> <n-notification-provider>
<n-dialog-provider> <n-dialog-provider>
@ -12,12 +16,36 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { zhCN, dateZhCN } from "naive-ui" import { zhCN, dateZhCN, darkTheme } from "naive-ui"
import GlobalLoading from "@/components/GlobalLoading.vue" import GlobalLoading from "@/components/GlobalLoading.vue"
import { checkAndUpdate } from "@/utils/updater" import { checkAndUpdate } from "@/utils/updater"
import { useSettingStore } from "@/stores/setting"
const settingStore = useSettingStore()
const media = window.matchMedia("(prefers-color-scheme: dark)")
const systemDark = ref(media.matches)
const themeMode = computed(() => settingStore.appearance.theme)
const isDark = computed(() => {
return themeMode.value === "dark" || (themeMode.value === "system" && systemDark.value)
})
watchEffect(() => {
document.documentElement.setAttribute("data-theme", isDark.value ? "dark" : "light")
})
const onSystemThemeChange = (e: MediaQueryListEvent) => {
systemDark.value = e.matches
}
onMounted(() => { onMounted(() => {
checkAndUpdate() checkAndUpdate()
media.addEventListener("change", onSystemThemeChange)
})
onUnmounted(() => {
media.removeEventListener("change", onSystemThemeChange)
}) })
</script> </script>

View File

@ -32,3 +32,20 @@
--set-item-title-size: 14px; --set-item-title-size: 14px;
--set-item-desc-size: 12px; --set-item-desc-size: 12px;
} }
/* 深色主题:通过根节点 data-theme="dark" 覆盖同名变量 */
:root[data-theme="dark"] {
--color-window-bg: #1b1c20;
--color-surface: #26272e;
--color-surface-hover: #30323b;
--color-text-primary: #f0f1f5;
--color-text-secondary: #9aa0ab;
--color-text-invert: #1d1d1f;
--color-border: rgba(255, 255, 255, 0.08);
--color-border-hover: rgba(102, 126, 234, 0.5);
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.35);
--shadow-card-hover: 0 10px 28px rgba(0, 0, 0, 0.5);
--shadow-focus: 0 4px 16px rgba(102, 126, 234, 0.3);
}

View File

@ -23,9 +23,13 @@ const isMacos = navigator.userAgent.includes("Mac OS X")
.container { .container {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background: rgba(255, 255, 255, 1); background: var(--color-window-bg);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2); border: 1px solid var(--color-border);
:deep(.n-layout) {
background: transparent;
}
} }
.header { .header {
@ -35,6 +39,6 @@ const isMacos = navigator.userAgent.includes("Mac OS X")
.content { .content {
background: transparent; background: transparent;
height: calc(100vh - 40px); height: calc(100vh - var(--titlebar-height));
} }
</style> </style>

View File

@ -38,6 +38,10 @@ const settingStore = useSettingStore()
const theme = ref(settingStore.appearance.theme) const theme = ref(settingStore.appearance.theme)
const showShadow = ref(settingStore.appearance.showShadow) const showShadow = ref(settingStore.appearance.showShadow)
watch(theme, (newVal) => {
settingStore.appearance.theme = newVal
})
watch(showShadow, (newVal) => { watch(showShadow, (newVal) => {
settingStore.appearance.showShadow = newVal settingStore.appearance.showShadow = newVal
getCurrentWindow().setShadow(newVal) getCurrentWindow().setShadow(newVal)