useTheme.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { storeToRefs } from "pinia";
  2. import { Theme } from "./interface";
  3. import { ElMessage } from "element-plus";
  4. import { DEFAULT_PRIMARY } from "@/config";
  5. import { useGlobalStore } from "@/stores/modules/global";
  6. import { getLightColor, getDarkColor } from "@/utils/color";
  7. import { menuTheme } from "@/styles/theme/menu";
  8. import { asideTheme } from "@/styles/theme/aside";
  9. import { headerTheme } from "@/styles/theme/header";
  10. /**
  11. * @description 全局主题 hooks
  12. * */
  13. export const useTheme = () => {
  14. const globalStore = useGlobalStore();
  15. const { primary, isDark, isGrey, isWeak, layout, asideInverted, headerInverted } = storeToRefs(globalStore);
  16. // 切换暗黑模式 ==> 同时修改主题颜色、侧边栏、头部颜色
  17. const switchDark = () => {
  18. const html = document.documentElement as HTMLElement;
  19. if (isDark.value) html.setAttribute("class", "dark");
  20. else html.setAttribute("class", "");
  21. changePrimary(primary.value);
  22. setAsideTheme();
  23. setHeaderTheme();
  24. };
  25. // 修改主题颜色
  26. const changePrimary = (val: string | null) => {
  27. if (!val) {
  28. val = DEFAULT_PRIMARY;
  29. ElMessage({ type: "success", message: `主题颜色已重置为 ${DEFAULT_PRIMARY}` });
  30. }
  31. // 计算主题颜色变化
  32. document.documentElement.style.setProperty("--el-color-primary", val);
  33. document.documentElement.style.setProperty(
  34. "--el-color-primary-dark-2",
  35. isDark.value ? `${getLightColor(val, 0.2)}` : `${getDarkColor(val, 0.3)}`
  36. );
  37. for (let i = 1; i <= 9; i++) {
  38. const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`;
  39. document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
  40. }
  41. globalStore.setGlobalState("primary", val);
  42. };
  43. // 灰色和弱色切换
  44. const changeGreyOrWeak = (type: Theme.GreyOrWeakType, value: boolean) => {
  45. const body = document.body as HTMLElement;
  46. if (!value) return body.removeAttribute("style");
  47. const styles: Record<Theme.GreyOrWeakType, string> = {
  48. grey: "filter: grayscale(1)",
  49. weak: "filter: invert(80%)"
  50. };
  51. body.setAttribute("style", styles[type]);
  52. const propName = type === "grey" ? "isWeak" : "isGrey";
  53. globalStore.setGlobalState(propName, false);
  54. };
  55. // 设置菜单样式
  56. const setMenuTheme = () => {
  57. let type: Theme.ThemeType = "light";
  58. if (layout.value === "transverse" && headerInverted.value) type = "inverted";
  59. if (layout.value !== "transverse" && asideInverted.value) type = "inverted";
  60. if (isDark.value) type = "dark";
  61. const theme = menuTheme[type!];
  62. for (const [key, value] of Object.entries(theme)) {
  63. document.documentElement.style.setProperty(key, value);
  64. }
  65. };
  66. // 设置侧边栏样式
  67. const setAsideTheme = () => {
  68. let type: Theme.ThemeType = "light";
  69. if (asideInverted.value) type = "inverted";
  70. if (isDark.value) type = "dark";
  71. const theme = asideTheme[type!];
  72. for (const [key, value] of Object.entries(theme)) {
  73. document.documentElement.style.setProperty(key, value);
  74. }
  75. setMenuTheme();
  76. };
  77. // 设置头部样式
  78. const setHeaderTheme = () => {
  79. let type: Theme.ThemeType = "light";
  80. if (headerInverted.value) type = "inverted";
  81. if (isDark.value) type = "dark";
  82. const theme = headerTheme[type!];
  83. for (const [key, value] of Object.entries(theme)) {
  84. document.documentElement.style.setProperty(key, value);
  85. }
  86. setMenuTheme();
  87. };
  88. // init theme
  89. const initTheme = () => {
  90. switchDark();
  91. if (isGrey.value) changeGreyOrWeak("grey", true);
  92. if (isWeak.value) changeGreyOrWeak("weak", true);
  93. };
  94. return {
  95. initTheme,
  96. switchDark,
  97. changePrimary,
  98. changeGreyOrWeak,
  99. setAsideTheme,
  100. setHeaderTheme
  101. };
  102. };