diff --git a/src/stores/app.ts b/src/stores/app.ts index 960f830..50e999b 100644 --- a/src/stores/app.ts +++ b/src/stores/app.ts @@ -4,7 +4,7 @@ import { ref } from 'vue' /** 主题类型:default / light / dark / green / purple / red */ export type ThemeMode = 'default' | 'light' | 'dark' | 'green' | 'purple' | 'red' -/** 主题色板:主色 + Element Plus 衍生色(light-N 为主色混白,dark-2 为主色混黑) */ +/** 主题色板:主色 + Element Plus 衍生色(浅色 light-N=混白、深色 light-N=混暗底) */ interface ThemePalette { /** 是否深色模式(驱动 html.dark) */ dark: boolean @@ -94,7 +94,8 @@ const PRIMARY_KEY = 'gerp-primary' /** * 十六进制颜色与白/黑按比例混合(对齐 Element Plus light-N/dark-2 派生规则) - * light-N:主色混白 N*10%;dark-2:主色混黑 20% + * 浅色主题:light-N = 主色混白 N*10%;深色主题:light-N = 主色混暗底 N*10% + * dark-2:浅色主题混黑 20%;深色主题反向提亮(混白 20%) */ function mixColor(hex: string, mix: string, weight: number): string { const parse = (c: string): [number, number, number] => { @@ -114,17 +115,29 @@ function mixColor(hex: string, mix: string, weight: number): string { return `#${[r, g, b].map((v) => v.toString(16).padStart(2, '0')).join('')}` } -/** 把主色应用到 Element Plus CSS 变量(含全部衍生色阶) */ -function applyPrimaryColor(color: string): void { +/** Element Plus 暗色主题 light-N 的混合基色(取 EP dark 变量 --el-bg-color: #141414) */ +const DARK_MIX_BASE = '#141414' + +/** + * 把主色应用到 Element Plus CSS 变量(含全部衍生色阶)。 + * + * 必须以「当前是否深色」区分混合基色:这里写入的是 documentElement 的内联变量, + * 优先级高于 Element Plus 的 html.dark 样式表;若两种模式都混白,深色下 + * light-9 仍是近白色(如 #ecf5ff),plain 按钮底色(= light-9)会变成深色界面里的 + * 一块近白补丁。深色取值与 EP 暗色主题逐值一致(light-9 #18222b / dark-2 #66b1ff)。 + */ +function applyPrimaryColor(color: string, isDark: boolean): void { const root = document.documentElement + const lightMix = isDark ? DARK_MIX_BASE : '#ffffff' + const darkMix = isDark ? '#ffffff' : '#000000' const vars: Record = { '--el-color-primary': color, - '--el-color-primary-light-3': mixColor(color, '#ffffff', 0.3), - '--el-color-primary-light-5': mixColor(color, '#ffffff', 0.5), - '--el-color-primary-light-7': mixColor(color, '#ffffff', 0.7), - '--el-color-primary-light-8': mixColor(color, '#ffffff', 0.8), - '--el-color-primary-light-9': mixColor(color, '#ffffff', 0.9), - '--el-color-primary-dark-2': mixColor(color, '#000000', 0.2), + '--el-color-primary-light-3': mixColor(color, lightMix, 0.3), + '--el-color-primary-light-5': mixColor(color, lightMix, 0.5), + '--el-color-primary-light-7': mixColor(color, lightMix, 0.7), + '--el-color-primary-light-8': mixColor(color, lightMix, 0.8), + '--el-color-primary-light-9': mixColor(color, lightMix, 0.9), + '--el-color-primary-dark-2': mixColor(color, darkMix, 0.2), } for (const [k, v] of Object.entries(vars)) { root.style.setProperty(k, v) @@ -153,7 +166,7 @@ export const useAppStore = defineStore('app', () => { root.classList.toggle('dark', cfg.dark) // vxe-table 暗色主题([data-vxe-ui-theme="dark"] 触发其内置暗色变量) root.setAttribute('data-vxe-ui-theme', cfg.dark ? 'dark' : 'light') - applyPrimaryColor(customPrimary.value ?? cfg.primary) + applyPrimaryColor(customPrimary.value ?? cfg.primary, cfg.dark) localStorage.setItem(THEME_KEY, value) } @@ -164,7 +177,7 @@ export const useAppStore = defineStore('app', () => { function setCustomColor(color: string | null): void { customPrimary.value = color const cfg = THEME_CONFIGS[theme.value] ?? THEME_CONFIGS.default - applyPrimaryColor(color ?? cfg.primary) + applyPrimaryColor(color ?? cfg.primary, cfg.dark) if (color) localStorage.setItem(PRIMARY_KEY, color) else localStorage.removeItem(PRIMARY_KEY) } @@ -179,7 +192,7 @@ export const useAppStore = defineStore('app', () => { const root = document.documentElement root.classList.toggle('dark', cfg.dark) root.setAttribute('data-vxe-ui-theme', cfg.dark ? 'dark' : 'light') - applyPrimaryColor(customPrimary.value ?? cfg.primary) + applyPrimaryColor(customPrimary.value ?? cfg.primary, cfg.dark) } /** 顶栏快捷切换:浅色主题 ↔ 深色主题(保持当前配色) */