2025-03-26
This commit is contained in:
87
src/hooks/useTheme.ts
Normal file
87
src/hooks/useTheme.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
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 { asideTheme, AsideThemeType } from "@/styles/theme/aside";
|
||||
|
||||
/**
|
||||
* @description 全局主题 hooks
|
||||
* */
|
||||
export const useTheme = () => {
|
||||
const globalStore = useGlobalStore();
|
||||
const { primary, isDark, isGrey, isWeak, asideInverted, layout } = 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();
|
||||
};
|
||||
|
||||
// 修改主题颜色
|
||||
const changePrimary = (val: string | null) => {
|
||||
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);
|
||||
}
|
||||
globalStore.setGlobalState("primary", val);
|
||||
};
|
||||
|
||||
// 灰色和弱色切换
|
||||
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);
|
||||
};
|
||||
|
||||
// 设置侧边栏样式 ==> light、inverted、dark
|
||||
const setAsideTheme = () => {
|
||||
// 默认所有侧边栏为 light 模式
|
||||
let type: AsideThemeType = "light";
|
||||
// 侧边栏反转色目前只支持在 vertical、classic 布局模式下生效 || transverse 布局下菜单栏默认为 inverted 模式
|
||||
if ((["vertical", "classic"].includes(layout.value) && asideInverted.value) || layout.value == "transverse") {
|
||||
type = "inverted";
|
||||
}
|
||||
// 侧边栏 dark 模式
|
||||
if (isDark.value) type = "dark";
|
||||
const theme = asideTheme[type!];
|
||||
for (const [key, value] of Object.entries(theme)) {
|
||||
document.documentElement.style.setProperty(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
// init theme
|
||||
const initTheme = () => {
|
||||
switchDark();
|
||||
if (isGrey.value) changeGreyOrWeak("grey", true);
|
||||
if (isWeak.value) changeGreyOrWeak("weak", true);
|
||||
};
|
||||
|
||||
return {
|
||||
initTheme,
|
||||
switchDark,
|
||||
changePrimary,
|
||||
changeGreyOrWeak,
|
||||
setAsideTheme
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user