From 7e47315cab1b32f8554654cb37bb219614358356 Mon Sep 17 00:00:00 2001 From: wf <2547096351@qq.com> Date: Mon, 6 May 2024 16:07:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=89=B2=E5=BC=B1=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E5=92=8C=E7=81=B0=E8=89=B2=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 5 +- src/hooks/useThemeMethods.ts | 57 ++++++++++++++++++- .../components/theme-settings/index.vue | 39 +++++++++++-- src/store/modules/theme-config.ts | 31 +++++++++- 4 files changed, 123 insertions(+), 9 deletions(-) diff --git a/src/App.vue b/src/App.vue index 8578f1a..f4ce8c6 100644 --- a/src/App.vue +++ b/src/App.vue @@ -10,9 +10,8 @@ import { useThemeMethods } from "@/hooks/useThemeMethods"; // 初始化主题 const onTheme = () => { - let { setDarkMode, setThemeColor } = useThemeMethods(); - setDarkMode(); - setThemeColor(); + let { initTheme } = useThemeMethods(); + initTheme(); }; onTheme(); diff --git a/src/hooks/useThemeMethods.ts b/src/hooks/useThemeMethods.ts index 408c094..9993ffa 100644 --- a/src/hooks/useThemeMethods.ts +++ b/src/hooks/useThemeMethods.ts @@ -3,6 +3,22 @@ import { useThemeConfig } from "@/store/modules/theme-config"; import { generate, getRgbStr } from "@arco-design/color"; /* 主题处理hooks */ export const useThemeMethods = () => { + /** + * @description: 初始化主题 + */ + const initTheme = () => { + // 黑暗模式和主题色 + setDarkMode(); + // 色弱模式和灰色模式 + const themeStore = useThemeConfig(); + const { grayMode } = storeToRefs(themeStore); + if (grayMode.value) { + setGray(); + } else { + setColorWeak(); + } + }; + /** * @description: 暗黑模式 */ @@ -16,6 +32,8 @@ export const useThemeMethods = () => { // 恢复亮色主题 document.body.removeAttribute("arco-theme"); } + // 黑暗模式切换后需要更新主题色 + setThemeColor(); }; /** @@ -33,8 +51,45 @@ export const useThemeMethods = () => { }); }; + /** + * @description: 色弱模式 + */ + const setColorWeak = () => { + // 获取html + const htmlCase = document.querySelector("html") as HTMLHtmlElement | null; + if (!htmlCase) return; + const themeStore = useThemeConfig(); + const { colorWeakMode, grayMode } = storeToRefs(themeStore); + if (colorWeakMode.value) { + grayMode.value = false; // 色弱模式和灰色模式互斥 + htmlCase.style.filter = "invert(80%)"; // 反转色80% + } else { + htmlCase.style.filter = ""; + } + }; + + /** + * @description: 灰色模式 + */ + const setGray = () => { + // 获取html + const htmlCase = document.querySelector("html") as HTMLHtmlElement | null; + if (!htmlCase) return; + const themeStore = useThemeConfig(); + const { colorWeakMode, grayMode } = storeToRefs(themeStore); + if (grayMode.value) { + colorWeakMode.value = false; // 色弱模式和灰色模式互斥 + htmlCase.style.filter = "grayscale(100%)"; // 灰度100% + } else { + htmlCase.style.filter = ""; + } + }; + return { + initTheme, setDarkMode, - setThemeColor + setThemeColor, + setColorWeak, + setGray }; }; diff --git a/src/layout/components/Header/components/theme-settings/index.vue b/src/layout/components/Header/components/theme-settings/index.vue index 5cec11f..f102309 100644 --- a/src/layout/components/Header/components/theme-settings/index.vue +++ b/src/layout/components/Header/components/theme-settings/index.vue @@ -18,17 +18,23 @@
主题设置
- +
色弱模式
- +
灰色模式
- +
侧边栏深色
@@ -52,7 +58,7 @@ import { useThemeConfig } from "@/store/modules/theme-config"; import { useThemeMethods } from "@/hooks/useThemeMethods"; const themeStore = useThemeConfig(); -const { layoutType, themeColor } = storeToRefs(themeStore); +const { layoutType, themeColor, presetColors, colorWeakMode, grayMode } = storeToRefs(themeStore); const layoutList = reactive({ layoutDefaults: { @@ -79,6 +85,18 @@ const themeColorChange = (value: string) => { setThemeColor(); }; +// 色弱模式 +const onColorWeak = () => { + const { setColorWeak } = useThemeMethods(); + setColorWeak(); +}; + +// 灰色模式 +const onGray = () => { + const { setGray } = useThemeMethods(); + setGray(); +}; + // 布局变化 const layouetChange = (type: string) => { layoutType.value = type; @@ -101,12 +119,14 @@ const handleCancel = () => { .box-gap { margin-top: 30px; } + .flex-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: $margin; } + .flex-center { display: flex; align-items: center; @@ -124,12 +144,15 @@ const handleCancel = () => { border-radius: $radius-box; overflow: hidden; box-shadow: $shadow-special; + .layout-icon { display: none; } } + .current-layout { position: relative; + .layout-icon { display: block; position: absolute; @@ -139,8 +162,10 @@ const handleCancel = () => { color: $color-primary; } } + .layout-defaults { position: relative; + &::before { content: ""; position: absolute; @@ -149,6 +174,7 @@ const handleCancel = () => { height: 100%; background: #232324; } + &::after { content: ""; position: absolute; @@ -159,8 +185,10 @@ const handleCancel = () => { background: #fff; } } + .layout-head { position: relative; + &::before { content: ""; position: absolute; @@ -170,8 +198,10 @@ const handleCancel = () => { background: #232324; } } + .layout-mixing { position: relative; + &::before { content: ""; position: absolute; @@ -180,6 +210,7 @@ const handleCancel = () => { height: 15px; background: #232324; } + &::after { content: ""; position: absolute; diff --git a/src/store/modules/theme-config.ts b/src/store/modules/theme-config.ts index 3b0bbba..7b37e83 100644 --- a/src/store/modules/theme-config.ts +++ b/src/store/modules/theme-config.ts @@ -15,7 +15,10 @@ interface ThemeConfig { watermarkRotate: number; watermarkGap: Array; layoutType: string; + grayMode: Boolean; + colorWeakMode: Boolean; themeColor: string; + presetColors: Array; } /** @@ -42,7 +45,33 @@ export const useThemeConfig = defineStore("theme-config", { watermarkRotate: 330, // 水印角度 watermarkGap: [100, 100], // 水印间隙 layoutType: "layoutDefaults", // 布局模式:layoutDefaults、layoutHead、layoutMixing - themeColor: "#165dff" // 主题色 + colorWeakMode: false, // 色弱模式 + grayMode: false, // 灰色模式 + themeColor: "#165DFF", // 主题色 + presetColors: [ + "#165DFF", + "#F53F3F", + "#F77234", + "#FF7D00", + "#F7BA1E", + "#FADC19", + "#9FDB1D", + "#00B42A", + "#14C9C9", + "#3491FA", + "#165DFF", + "#722ED1", + "#D91AD9", + "#F5319D", + "#67C23A", + "#E6A23C", + "#F56C6C", + "#409EFF", + "#a27b42", + "#dfc683", + "#59a680", + "#b1d391" + ] }), actions: { // 折叠菜单