index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <script setup lang="ts">
  2. import panel from "../panel/index.vue";
  3. import { useRouter } from "vue-router";
  4. import { emitter } from "/@/utils/mitt";
  5. import { templateRef } from "@vueuse/core";
  6. import { reactive, ref, unref, useCssModule } from "vue";
  7. import { storageLocal, storageSession } from "/@/utils/storage";
  8. const router = useRouter();
  9. const { isSelect } = useCssModule();
  10. // 默认灵动模式
  11. const markValue = ref(storageLocal.getItem("showModel") || "smart");
  12. const logoVal = ref(storageLocal.getItem("logoVal") || "1");
  13. const localOperate = (key: string, value?: any, model?: string): any => {
  14. model && model === "set"
  15. ? storageLocal.setItem(key, value)
  16. : storageLocal.getItem(key);
  17. };
  18. const settings = reactive({
  19. greyVal: storageLocal.getItem("greyVal"),
  20. weekVal: storageLocal.getItem("weekVal"),
  21. tagsVal: storageLocal.getItem("tagsVal")
  22. });
  23. settings.greyVal === null
  24. ? localOperate("greyVal", false, "set")
  25. : document.querySelector("html")?.setAttribute("class", "html-grey");
  26. settings.weekVal === null
  27. ? localOperate("weekVal", false, "set")
  28. : document.querySelector("html")?.setAttribute("class", "html-weakness");
  29. function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
  30. const targetEl = target || document.body;
  31. let { className } = targetEl;
  32. className = className.replace(clsName, "");
  33. targetEl.className = flag ? `${className} ${clsName} ` : className;
  34. }
  35. // 灰色模式设置
  36. const greyChange = ({ value }): void => {
  37. toggleClass(settings.greyVal, "html-grey", document.querySelector("html"));
  38. value
  39. ? localOperate("greyVal", true, "set")
  40. : localOperate("greyVal", false, "set");
  41. };
  42. // 色弱模式设置
  43. const weekChange = ({ value }): void => {
  44. toggleClass(
  45. settings.weekVal,
  46. "html-weakness",
  47. document.querySelector("html")
  48. );
  49. value
  50. ? localOperate("weekVal", true, "set")
  51. : localOperate("weekVal", false, "set");
  52. };
  53. const tagsChange = () => {
  54. let showVal = settings.tagsVal;
  55. showVal
  56. ? storageLocal.setItem("tagsVal", true)
  57. : storageLocal.setItem("tagsVal", false);
  58. emitter.emit("tagViewsChange", showVal);
  59. };
  60. function onReset() {
  61. storageLocal.clear();
  62. storageSession.clear();
  63. router.push("/login");
  64. }
  65. function onChange({ label }) {
  66. storageLocal.setItem("showModel", label);
  67. emitter.emit("tagViewsShowModel", label);
  68. }
  69. const firstTheme = templateRef<HTMLElement | null>("firstTheme", null);
  70. const secondTheme = templateRef<HTMLElement | null>("secondTheme", null);
  71. const dataTheme = ref(storageLocal.getItem("data-theme") || "dark");
  72. if (dataTheme.value) {
  73. storageLocal.setItem("data-theme", unref(dataTheme));
  74. window.document.body.setAttribute("data-theme", unref(dataTheme));
  75. }
  76. // dark主题
  77. function onDark() {
  78. storageLocal.setItem("data-theme", "dark");
  79. window.document.body.setAttribute("data-theme", "dark");
  80. toggleClass(true, isSelect, unref(firstTheme));
  81. toggleClass(false, isSelect, unref(secondTheme));
  82. }
  83. // light主题
  84. function onLight() {
  85. storageLocal.setItem("data-theme", "light");
  86. window.document.body.setAttribute("data-theme", "light");
  87. toggleClass(false, isSelect, unref(firstTheme));
  88. toggleClass(true, isSelect, unref(secondTheme));
  89. }
  90. function logoChange() {
  91. unref(logoVal) === "1"
  92. ? storageLocal.setItem("logoVal", "1")
  93. : storageLocal.setItem("logoVal", "-1");
  94. emitter.emit("logoChange", unref(logoVal));
  95. }
  96. </script>
  97. <template>
  98. <panel>
  99. <el-divider>主题风格</el-divider>
  100. <ul class="theme-stley">
  101. <el-tooltip
  102. class="item"
  103. effect="dark"
  104. content="暗色主题"
  105. placement="bottom"
  106. >
  107. <li
  108. :class="dataTheme === 'dark' ? $style.isSelect : ''"
  109. ref="firstTheme"
  110. @click="onDark"
  111. >
  112. <div></div>
  113. <div></div>
  114. </li>
  115. </el-tooltip>
  116. <el-tooltip
  117. class="item"
  118. effect="dark"
  119. content="亮色主题"
  120. placement="bottom"
  121. >
  122. <li
  123. :class="dataTheme === 'light' ? $style.isSelect : ''"
  124. ref="secondTheme"
  125. @click="onLight"
  126. >
  127. <div></div>
  128. <div></div>
  129. </li>
  130. </el-tooltip>
  131. </ul>
  132. <el-divider>界面显示</el-divider>
  133. <ul class="setting">
  134. <li>
  135. <span>灰色模式</span>
  136. <vxe-switch
  137. v-model="settings.greyVal"
  138. open-label="开"
  139. close-label="关"
  140. @change="greyChange"
  141. ></vxe-switch>
  142. </li>
  143. <li>
  144. <span>色弱模式</span>
  145. <vxe-switch
  146. v-model="settings.weekVal"
  147. open-label="开"
  148. close-label="关"
  149. @change="weekChange"
  150. ></vxe-switch>
  151. </li>
  152. <li>
  153. <span>隐藏标签页</span>
  154. <vxe-switch
  155. v-model="settings.tagsVal"
  156. open-label="开"
  157. close-label="关"
  158. @change="tagsChange"
  159. ></vxe-switch>
  160. </li>
  161. <li>
  162. <span>侧边栏Logo</span>
  163. <vxe-switch
  164. v-model="logoVal"
  165. open-value="1"
  166. close-value="-1"
  167. open-label="开"
  168. close-label="关"
  169. @change="logoChange"
  170. ></vxe-switch>
  171. </li>
  172. <li>
  173. <span>标签风格</span>
  174. <vxe-radio-group v-model="markValue" @change="onChange">
  175. <vxe-radio label="card" content="卡片"></vxe-radio>
  176. <vxe-radio label="smart" content="灵动"></vxe-radio>
  177. </vxe-radio-group>
  178. </li>
  179. </ul>
  180. <el-divider />
  181. <vxe-button
  182. status="danger"
  183. style="width: 90%; margin: 24px 15px"
  184. content="清空缓存并返回登录页"
  185. icon="fa fa-sign-out"
  186. @click="onReset"
  187. ></vxe-button>
  188. </panel>
  189. </template>
  190. <style scoped module>
  191. .isSelect {
  192. border: 2px solid #0960bd;
  193. }
  194. </style>
  195. <style lang="scss" scoped>
  196. .setting {
  197. width: 100%;
  198. li {
  199. display: flex;
  200. justify-content: space-between;
  201. align-items: center;
  202. margin: 25px;
  203. }
  204. }
  205. :deep(.el-divider__text) {
  206. font-size: 16px;
  207. font-weight: 700;
  208. }
  209. .theme-stley {
  210. margin-top: 25px;
  211. width: 100%;
  212. height: 60px;
  213. display: flex;
  214. justify-content: space-around;
  215. li {
  216. width: 30%;
  217. height: 100%;
  218. background: #f0f2f5;
  219. position: relative;
  220. overflow: hidden;
  221. cursor: pointer;
  222. background-color: #f0f2f5;
  223. border-radius: 4px;
  224. box-shadow: 0 1px 2.5px 0 rgb(0 0 0 / 18%);
  225. &:nth-child(1) {
  226. div {
  227. &:nth-child(1) {
  228. width: 30%;
  229. height: 100%;
  230. background: #1b2a47;
  231. }
  232. &:nth-child(2) {
  233. width: 70%;
  234. height: 30%;
  235. top: 0;
  236. right: 0;
  237. background-color: #fff;
  238. box-shadow: 0 0 1px #888;
  239. position: absolute;
  240. }
  241. }
  242. }
  243. &:nth-child(2) {
  244. div {
  245. &:nth-child(1) {
  246. width: 30%;
  247. height: 100%;
  248. box-shadow: 0 0 1px #888;
  249. background-color: #fff;
  250. border-radius: 4px 0 0 4px;
  251. }
  252. &:nth-child(2) {
  253. width: 70%;
  254. height: 30%;
  255. top: 0;
  256. right: 0;
  257. background-color: #fff;
  258. box-shadow: 0 0 1px #888;
  259. position: absolute;
  260. }
  261. }
  262. }
  263. }
  264. }
  265. </style>