Files
pqs-9100_client/frontend/src/hooks/useTheme.ts

116 lines
3.9 KiB
TypeScript
Raw Normal View History

2024-08-22 11:27:06 +08:00
import { storeToRefs } from "pinia";
import { Theme } from "./interface";
import { ElMessage } from "element-plus";
import { DEFAULT_PRIMARY } from "@/config";
import { useGlobalStore } from "@/stores/modules/global";
import { getLightColor, getDarkColor } from "@/utils/color";
import { menuTheme } from "@/styles/theme/menu";
import { asideTheme } from "@/styles/theme/aside";
import { headerTheme } from "@/styles/theme/header";
/**
* @description hooks
* */
export const useTheme = () => {
const globalStore = useGlobalStore();
const { primary, isDark, isGrey, isWeak, layout, asideInverted, headerInverted } = storeToRefs(globalStore);
// 切换暗黑模式 ==> 同时修改主题颜色、侧边栏、头部颜色
const switchDark = () => {
const html = document.documentElement as HTMLElement;
if (isDark.value) html.setAttribute("class", "dark");
else html.setAttribute("class", "");
changePrimary(primary.value);
setAsideTheme();
setHeaderTheme();
};
// 修改主题颜色
const changePrimary = (val: string | null) => {
2025-03-17 15:55:30 +08:00
2024-08-22 11:27:06 +08:00
if (!val) {
val = DEFAULT_PRIMARY;
ElMessage({ type: "success", message: `主题颜色已重置为 ${DEFAULT_PRIMARY}` });
}
// 计算主题颜色变化
document.documentElement.style.setProperty("--el-color-primary", val);
document.documentElement.style.setProperty(
"--el-color-primary-dark-2",
isDark.value ? `${getLightColor(val, 0.2)}` : `${getDarkColor(val, 0.3)}`
);
for (let i = 1; i <= 9; i++) {
const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`;
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
2025-03-19 10:26:41 +08:00
// const colorValue = document.documentElement.style.getPropertyValue(`--el-color-primary-light-${i}`).trim();
// console.log(`--el-color-primary-light-${i}: ${colorValue}`);
2024-08-22 11:27:06 +08:00
}
globalStore.setGlobalState("primary", val);
2025-03-19 10:26:41 +08:00
2025-03-17 15:55:30 +08:00
}
2024-08-22 11:27:06 +08:00
// 灰色和弱色切换
const changeGreyOrWeak = (type: Theme.GreyOrWeakType, value: boolean) => {
const body = document.body as HTMLElement;
if (!value) return body.removeAttribute("style");
const styles: Record<Theme.GreyOrWeakType, string> = {
grey: "filter: grayscale(1)",
weak: "filter: invert(80%)"
};
body.setAttribute("style", styles[type]);
const propName = type === "grey" ? "isWeak" : "isGrey";
globalStore.setGlobalState(propName, false);
};
// 设置菜单样式
const setMenuTheme = () => {
let type: Theme.ThemeType = "light";
if (layout.value === "transverse" && headerInverted.value) type = "inverted";
if (layout.value !== "transverse" && asideInverted.value) type = "inverted";
if (isDark.value) type = "dark";
const theme = menuTheme[type!];
for (const [key, value] of Object.entries(theme)) {
document.documentElement.style.setProperty(key, value);
}
};
// 设置侧边栏样式
const setAsideTheme = () => {
let type: Theme.ThemeType = "light";
if (asideInverted.value) type = "inverted";
if (isDark.value) type = "dark";
const theme = asideTheme[type!];
for (const [key, value] of Object.entries(theme)) {
document.documentElement.style.setProperty(key, value);
}
setMenuTheme();
};
// 设置头部样式
const setHeaderTheme = () => {
let type: Theme.ThemeType = "light";
if (headerInverted.value) type = "inverted";
if (isDark.value) type = "dark";
const theme = headerTheme[type!];
for (const [key, value] of Object.entries(theme)) {
document.documentElement.style.setProperty(key, value);
}
setMenuTheme();
};
// init theme
const initTheme = () => {
switchDark();
if (isGrey.value) changeGreyOrWeak("grey", true);
if (isWeak.value) changeGreyOrWeak("weak", true);
};
return {
initTheme,
switchDark,
changePrimary,
changeGreyOrWeak,
setAsideTheme,
setHeaderTheme
};
};