useDataThemeChange.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { ref } from "vue";
  2. import { getConfig } from "@/config";
  3. import { useLayout } from "./useLayout";
  4. import { removeToken } from "@/utils/auth";
  5. import { routerArrays } from "@/layout/types";
  6. import { router, resetRouter } from "@/router";
  7. import type { themeColorsType } from "../types";
  8. import { useAppStoreHook } from "@/store/modules/app";
  9. import { useEpThemeStoreHook } from "@/store/modules/epTheme";
  10. import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
  11. import { darken, lighten, useGlobal, storageLocal } from "@pureadmin/utils";
  12. export function useDataThemeChange() {
  13. const { layoutTheme, layout } = useLayout();
  14. const themeColors = ref<Array<themeColorsType>>([
  15. /* 亮白色 */
  16. { color: "#ffffff", themeColor: "light" },
  17. /* 道奇蓝 */
  18. { color: "#1b2a47", themeColor: "default" },
  19. /* 深紫罗兰色 */
  20. { color: "#722ed1", themeColor: "saucePurple" },
  21. /* 深粉色 */
  22. { color: "#eb2f96", themeColor: "pink" },
  23. /* 猩红色 */
  24. { color: "#f5222d", themeColor: "dusk" },
  25. /* 橙红色 */
  26. { color: "#fa541c", themeColor: "volcano" },
  27. /* 绿宝石 */
  28. { color: "#13c2c2", themeColor: "mingQing" },
  29. /* 酸橙绿 */
  30. { color: "#52c41a", themeColor: "auroraGreen" }
  31. ]);
  32. const { $storage } = useGlobal<GlobalPropertiesApi>();
  33. const dataTheme = ref<boolean>($storage?.layout?.darkMode);
  34. const overallStyle = ref<string>($storage?.layout?.overallStyle);
  35. const body = document.documentElement as HTMLElement;
  36. function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
  37. const targetEl = target || document.body;
  38. let { className } = targetEl;
  39. className = className.replace(clsName, "").trim();
  40. targetEl.className = flag ? `${className} ${clsName}` : className;
  41. }
  42. /** 设置导航主题色 */
  43. function setLayoutThemeColor(
  44. theme = getConfig().Theme ?? "light",
  45. isClick = true
  46. ) {
  47. layoutTheme.value.theme = theme;
  48. document.documentElement.setAttribute("data-theme", theme);
  49. // 如果非isClick,保留之前的themeColor
  50. const storageThemeColor = $storage.layout.themeColor;
  51. $storage.layout = {
  52. layout: layout.value,
  53. theme,
  54. darkMode: dataTheme.value,
  55. sidebarStatus: $storage.layout?.sidebarStatus,
  56. epThemeColor: $storage.layout?.epThemeColor,
  57. themeColor: isClick ? theme : storageThemeColor,
  58. overallStyle: overallStyle.value
  59. };
  60. if (theme === "default" || theme === "light") {
  61. setEpThemeColor(getConfig().EpThemeColor);
  62. } else {
  63. const colors = themeColors.value.find(v => v.themeColor === theme);
  64. setEpThemeColor(colors.color);
  65. }
  66. }
  67. function setPropertyPrimary(mode: string, i: number, color: string) {
  68. document.documentElement.style.setProperty(
  69. `--el-color-primary-${mode}-${i}`,
  70. dataTheme.value ? darken(color, i / 10) : lighten(color, i / 10)
  71. );
  72. }
  73. /** 设置 `element-plus` 主题色 */
  74. const setEpThemeColor = (color: string) => {
  75. useEpThemeStoreHook().setEpThemeColor(color);
  76. document.documentElement.style.setProperty("--el-color-primary", color);
  77. for (let i = 1; i <= 2; i++) {
  78. setPropertyPrimary("dark", i, color);
  79. }
  80. for (let i = 1; i <= 9; i++) {
  81. setPropertyPrimary("light", i, color);
  82. }
  83. };
  84. /** 浅色、深色整体风格切换 */
  85. function dataThemeChange(overall?: string) {
  86. overallStyle.value = overall;
  87. if (useEpThemeStoreHook().epTheme === "light" && dataTheme.value) {
  88. setLayoutThemeColor("default", false);
  89. } else {
  90. setLayoutThemeColor(useEpThemeStoreHook().epTheme, false);
  91. }
  92. if (dataTheme.value) {
  93. document.documentElement.classList.add("dark");
  94. } else {
  95. if ($storage.layout.themeColor === "light") {
  96. setLayoutThemeColor("light", false);
  97. }
  98. document.documentElement.classList.remove("dark");
  99. }
  100. }
  101. /** 清空缓存并返回登录页 */
  102. function onReset() {
  103. removeToken();
  104. storageLocal().clear();
  105. const { Grey, Weak, MultiTagsCache, EpThemeColor, Layout } = getConfig();
  106. useAppStoreHook().setLayout(Layout);
  107. setEpThemeColor(EpThemeColor);
  108. useMultiTagsStoreHook().multiTagsCacheChange(MultiTagsCache);
  109. toggleClass(Grey, "html-grey", document.querySelector("html"));
  110. toggleClass(Weak, "html-weakness", document.querySelector("html"));
  111. router.push("/login");
  112. useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
  113. resetRouter();
  114. }
  115. return {
  116. body,
  117. dataTheme,
  118. overallStyle,
  119. layoutTheme,
  120. themeColors,
  121. onReset,
  122. toggleClass,
  123. dataThemeChange,
  124. setEpThemeColor,
  125. setLayoutThemeColor
  126. };
  127. }