From e212a0ab75e1c59d0d030ac0b2f07048f6a0f9cf Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: 星期三, 04 十二月 2024 20:32:06 +0800
Subject: [PATCH] 支持开启暗黑模式
---
src/assets/styles/sidebar.scss | 6
src/layout/components/Navbar.vue | 28 ++
src/layout/components/TagsView/index.vue | 41 ++-
src/assets/styles/variables.module.scss | 235 ++++++++++++++++---
src/store/modules/settings.js | 14 +
src/assets/icons/svg/sunny.svg | 1
src/assets/styles/ruoyi.scss | 64 +++--
/dev/null | 156 -------------
src/components/Hamburger/index.vue | 1
src/layout/components/Sidebar/Logo.vue | 30 ++
src/main.js | 4
src/components/TopNav/index.vue | 4
src/layout/components/Sidebar/index.vue | 66 ++++
src/assets/icons/svg/moon.svg | 1
src/layout/components/Settings/index.vue | 13
src/components/Crontab/index.vue | 1
16 files changed, 392 insertions(+), 273 deletions(-)
diff --git a/src/assets/icons/svg/moon.svg b/src/assets/icons/svg/moon.svg
new file mode 100644
index 0000000..ec72d77
--- /dev/null
+++ b/src/assets/icons/svg/moon.svg
@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733303018722" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1447" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M368.832 67.2c51.328-16.384 89.216 34.112 75.712 76.416a346.816 346.816 0 0 0 435.84 435.84c42.304-13.44 92.8 24.384 76.48 75.712A467.968 467.968 0 1 1 368.832 67.2z m-35.776 122.688a368.832 368.832 0 1 0 501.056 501.056 445.952 445.952 0 0 1-501.056-501.056z" p-id="1448"></path></svg>
\ No newline at end of file
diff --git a/src/assets/icons/svg/sunny.svg b/src/assets/icons/svg/sunny.svg
new file mode 100644
index 0000000..cc628bf
--- /dev/null
+++ b/src/assets/icons/svg/sunny.svg
@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733303115132" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12397" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 890.432c18.432 0 33.408 14.976 33.408 33.408v66.752a33.408 33.408 0 0 1-66.816 0v-66.752c0-18.432 14.976-33.408 33.408-33.408z m-267.52-110.848a33.408 33.408 0 0 1 0 47.232l-47.296 47.232a33.408 33.408 0 0 1-47.232-47.232l47.232-47.232a33.408 33.408 0 0 1 47.232 0z m582.336 0l47.232 47.232a33.408 33.408 0 0 1-47.232 47.232l-47.232-47.232a33.408 33.408 0 1 1 47.232-47.232zM512 200.32a311.68 311.68 0 1 1 0 623.296 311.68 311.68 0 0 1 0-623.36z m0 66.752a244.864 244.864 0 1 0 0 489.728 244.864 244.864 0 0 0 0-489.728zM100.16 478.592a33.408 33.408 0 1 1 0 66.816H33.408a33.408 33.408 0 0 1 0-66.816h66.752z m890.432 0a33.408 33.408 0 0 1 0 66.816h-66.752a33.408 33.408 0 1 1 0-66.816h66.752zM197.184 149.952l47.232 47.232a33.408 33.408 0 1 1-47.232 47.232l-47.232-47.232a33.408 33.408 0 0 1 47.232-47.232z m676.864 0a33.408 33.408 0 0 1 0 47.232l-47.232 47.232a33.408 33.408 0 1 1-47.232-47.232l47.232-47.232a33.408 33.408 0 0 1 47.232 0zM512 0c18.432 0 33.408 14.976 33.408 33.408v66.752a33.408 33.408 0 1 1-66.816 0V33.408C478.592 14.976 493.568 0 512 0z" p-id="12398"></path></svg>
\ No newline at end of file
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index fa551d3..4996ae5 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -1,4 +1,4 @@
- /**
+/**
* 閫氱敤css鏍峰紡甯冨眬澶勭悊
* Copyright (c) 2019 ruoyi
*/
@@ -102,38 +102,53 @@
/** 琛ㄦ牸甯冨眬 **/
.pagination-container {
- position: relative;
- height: 32px;
- margin-bottom: 10px;
- margin-top: 15px;
- padding: 10px 20px !important;
+ position: relative;
+ height: 25px;
+ margin-bottom: 10px;
+ margin-top: 15px;
+ padding: 10px 20px !important;
+ background-color: transparent !important;
}
+/* 鍒嗛〉鍣ㄥ畾浣� */
+.pagination-container .el-pagination {
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+
+/* 寮圭獥涓殑鍒嗛〉鍣� */
.el-dialog .pagination-container {
- position: static !important;
+ position: static !important;
+ margin: 10px 0 0 0;
+ padding: 0 !important;
+
+ .el-pagination {
+ position: static;
+ }
+}
+
+/* 绉诲姩绔�傞厤 */
+@media (max-width: 768px) {
+ .pagination-container {
+ .el-pagination {
+ > .el-pagination__jump {
+ display: none !important;
+ }
+ > .el-pagination__sizes {
+ display: none !important;
+ }
+ }
+ }
}
/* tree border */
.tree-border {
margin-top: 5px;
- border: 1px solid #e5e6e7;
- background: #FFFFFF none;
+ border: 1px solid var(--el-border-color-light, #e5e6e7);
+ background: var(--el-bg-color, #FFFFFF) none;
border-radius:4px;
width: 100%;
-}
-
-.pagination-container .el-pagination {
- right: 0;
- position: absolute;
-}
-
-@media ( max-width : 768px) {
- .pagination-container .el-pagination > .el-pagination__jump {
- display: none !important;
- }
- .pagination-container .el-pagination > .el-pagination__sizes {
- display: none !important;
- }
}
.el-table .fixed-width .el-button--small {
@@ -282,6 +297,5 @@
/* 鍒嗗壊闈㈡澘鏍峰紡 */
.splitpanes.default-theme .splitpanes__pane {
- background-color: #fff!important;
+ background-color: var(--splitpanes-default-bg) !important;
}
-
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index df7a62f..89820d1 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -1,7 +1,7 @@
#app {
.main-container {
- height: 100%;
+ min-height: 100%;
transition: margin-left .28s;
margin-left: $base-sidebar-width;
position: relative;
@@ -12,10 +12,8 @@
}
.sidebar-container {
- -webkit-transition: width .28s;
transition: width 0.28s;
width: $base-sidebar-width !important;
- background-color: $base-menu-background;
height: 100%;
position: fixed;
font-size: 0px;
@@ -103,7 +101,7 @@
& .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
& .theme-dark .el-sub-menu .el-menu-item {
- background-color: $base-sub-menu-background !important;
+ background-color: $base-sub-menu-background;
&:hover {
background-color: $base-sub-menu-hover !important;
diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss
index e065775..27941ab 100644
--- a/src/assets/styles/variables.module.scss
+++ b/src/assets/styles/variables.module.scss
@@ -8,58 +8,211 @@
$yellow: #FEC171;
$panGreen: #30B08F;
-// 榛樿鑿滃崟涓婚椋庢牸
+// 榛樿涓婚鍙橀噺
+$menuText: #bfcbd9;
+$menuActiveText: #409eff;
+$menuBg: #304156;
+$menuHover: #263445;
+
+// 娴呰壊涓婚theme-light
+$menuLightBg: #ffffff;
+$menuLightHover: #f0f1f5;
+$menuLightText: #303133;
+$menuLightActiveText: #409EFF;
+
+// 鍩虹鍙橀噺
+$base-sidebar-width: 200px;
+$sideBarWidth: 200px;
+
+// 鑿滃崟鏆楄壊鍙橀噺
$base-menu-color: #bfcbd9;
$base-menu-color-active: #f4f4f5;
$base-menu-background: #304156;
-$base-logo-title-color: #ffffff;
-
-$base-menu-light-color: rgba(0, 0, 0, 0.7);
-$base-menu-light-background: #ffffff;
-$base-logo-light-title-color: #001529;
-
$base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover: #001528;
-// 鑷畾涔夋殫鑹茶彍鍗曢鏍�
-/**
-$base-menu-color:hsla(0,0%,100%,.65);
-$base-menu-color-active:#fff;
-$base-menu-background:#001529;
-$base-logo-title-color: #ffffff;
-
-$base-menu-light-color:rgba(0,0,0,.70);
-$base-menu-light-background:#ffffff;
-$base-logo-light-title-color: #001529;
-
-$base-sub-menu-background:#000c17;
-$base-sub-menu-hover:#001528;
-*/
-
+// 缁勪欢鍙橀噺
$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-info: #909399;
-$base-sidebar-width: 200px;
-
-// the :export directive is the magic sauce for webpack
-// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
- menuColor: $base-menu-color;
- menuLightColor: $base-menu-light-color;
- menuColorActive: $base-menu-color-active;
- menuBackground: $base-menu-background;
- menuLightBackground: $base-menu-light-background;
- subMenuBackground: $base-sub-menu-background;
- subMenuHover: $base-sub-menu-hover;
- sideBarWidth: $base-sidebar-width;
- logoTitleColor: $base-logo-title-color;
- logoLightTitleColor: $base-logo-light-title-color;
- primaryColor: $--color-primary;
- successColor: $--color-success;
- dangerColor: $--color-danger;
- infoColor: $--color-info;
- warningColor: $--color-warning;
+ menuText: $menuText;
+ menuActiveText: $menuActiveText;
+ menuBg: $menuBg;
+ menuHover: $menuHover;
+ menuLightBg: $menuLightBg;
+ menuLightHover: $menuLightHover;
+ menuLightText: $menuLightText;
+ menuLightActiveText: $menuLightActiveText;
+ sideBarWidth: $sideBarWidth;
+ // 瀵煎嚭鍩虹棰滆壊
+ blue: $blue;
+ lightBlue: $light-blue;
+ red: $red;
+ pink: $pink;
+ green: $green;
+ tiffany: $tiffany;
+ yellow: $yellow;
+ panGreen: $panGreen;
+ // 瀵煎嚭缁勪欢棰滆壊
+ colorPrimary: $--color-primary;
+ colorSuccess: $--color-success;
+ colorWarning: $--color-warning;
+ colorDanger: $--color-danger;
+ colorInfo: $--color-info;
}
+
+// CSS鍙橀噺瀹氫箟
+:root {
+ /* 浜壊妯″紡鍙橀噺 */
+ --sidebar-bg: #{$menuBg};
+ --sidebar-text: #{$menuText};
+ --menu-hover: #{$menuHover};
+
+ --navbar-bg: #ffffff;
+ --navbar-text: #303133;
+
+ /* splitpanes default-theme 鍙橀噺 */
+ --splitpanes-default-bg: #ffffff;
+
+}
+
+// 鏆楅粦妯″紡鍙橀噺
+html.dark {
+ /* 榛樿閫氱敤 */
+ --el-bg-color: #141414;
+ --el-bg-color-overlay: #1d1e1f;
+ --el-text-color-primary: #ffffff;
+ --el-text-color-regular: #d0d0d0;
+ --el-border-color: #434343;
+ --el-border-color-light: #434343;
+
+ /* 渚ц竟鏍� */
+ --sidebar-bg: #141414;
+ --sidebar-text: #ffffff;
+ --menu-hover: #2d2d2d;
+ --menu-active-text: #{$menuActiveText};
+
+ /* 椤堕儴瀵艰埅鏍� */
+ --navbar-bg: #141414;
+ --navbar-text: #ffffff;
+ --navbar-hover: #141414;
+
+ /* 鏍囩鏍� */
+ --tags-bg: #141414;
+ --tags-item-bg: #1d1e1f;
+ --tags-item-border: #303030;
+ --tags-item-text: #d0d0d0;
+ --tags-item-hover: #2d2d2d;
+ --tags-close-hover: #64666a;
+
+ /* splitpanes 缁勪欢鏆楅粦妯″紡鍙橀噺 */
+ --splitpanes-bg: #141414;
+ --splitpanes-border: #303030;
+ --splitpanes-splitter-bg: #1d1e1f;
+ --splitpanes-splitter-hover-bg: #2d2d2d;
+
+ /* blockquote 鏆楅粦妯″紡鍙橀噺 */
+ --blockquote-bg: #1d1e1f;
+ --blockquote-border: #303030;
+ --blockquote-text: #d0d0d0;
+
+ /* Cron 鏃堕棿琛ㄨ揪寮� 妯″紡鍙橀噺 */
+ --cron-border: #303030;
+
+ /* splitpanes default-theme 鏆楅粦妯″紡鍙橀噺 */
+ --splitpanes-default-bg: #141414;
+
+ /* 渚ц竟鏍忚彍鍗曡鐩� */
+ .sidebar-container {
+ & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
+ & .theme-dark .el-sub-menu .el-menu-item {
+ background-color: var(--el-bg-color) !important;
+ }
+ }
+
+ /* 椤堕儴鏍忔爮鑿滃崟瑕嗙洊 */
+ .el-menu--horizontal {
+ .el-menu-item {
+ &:not(.is-disabled) {
+ &:hover,
+ &:focus {
+ background-color: var(--navbar-hover) !important;
+ }
+ }
+ }
+ }
+
+ /* 鍒嗗壊绐楁牸瑕嗙洊 */
+ .splitpanes {
+ background-color: var(--splitpanes-bg);
+
+ .splitpanes__pane {
+ background-color: var(--splitpanes-bg);
+ border-color: var(--splitpanes-border);
+ }
+
+ .splitpanes__splitter {
+ background-color: var(--splitpanes-splitter-bg);
+ border-color: var(--splitpanes-border);
+
+ &:hover {
+ background-color: var(--splitpanes-splitter-hover-bg);
+ }
+
+ &:before,
+ &:after {
+ background-color: var(--splitpanes-border);
+ }
+ }
+ }
+
+ /* 琛ㄦ牸鏍峰紡瑕嗙洊 */
+ .el-table {
+ --el-table-header-bg-color: var(--el-bg-color-overlay) !important;
+ --el-table-header-text-color: var(--el-text-color-regular) !important;
+ --el-table-border-color: var(--el-border-color-light) !important;
+ --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important;
+
+ .el-table__header-wrapper, .el-table__fixed-header-wrapper {
+ th {
+ background-color: var(--el-bg-color-overlay, #f8f8f9) !important;
+ color: var(--el-text-color-regular, #515a6e);
+ }
+ }
+ }
+
+ /* 鏍戠粍浠堕珮浜牱寮忚鐩� */
+ .el-tree {
+ .el-tree-node.is-current > .el-tree-node__content {
+ background-color: var(--el-bg-color-overlay) !important;
+ color: var(--el-color-primary);
+ }
+
+ .el-tree-node__content:hover {
+ background-color: var(--el-bg-color-overlay);
+ }
+ }
+
+ /* 涓嬫媺鑿滃崟鏍峰紡瑕嗙洊 */
+ .el-dropdown-menu__item:not(.is-disabled):focus, .el-dropdown-menu__item:not(.is-disabled):hover{
+ background-color: var(--navbar-hover) !important;
+ }
+
+ /* blockquote鏍峰紡瑕嗙洊 */
+ blockquote {
+ background-color: var(--blockquote-bg) !important;
+ border-left-color: var(--blockquote-border) !important;
+ color: var(--blockquote-text) !important;
+ }
+
+ /* 鏃堕棿琛ㄨ揪寮忔爣棰樻牱寮忚鐩� */
+ .popup-result .title {
+ background: var(--cron-border);
+ }
+
+}
+
diff --git a/src/components/Crontab/index.vue b/src/components/Crontab/index.vue
index f1d7201..71f3824 100644
--- a/src/components/Crontab/index.vue
+++ b/src/components/Crontab/index.vue
@@ -251,7 +251,6 @@
.popup-main {
position: relative;
margin: 10px auto;
- background: #fff;
border-radius: 5px;
font-size: 12px;
overflow: hidden;
diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue
index 8b6f7a8..ab1dc36 100644
--- a/src/components/Hamburger/index.vue
+++ b/src/components/Hamburger/index.vue
@@ -7,6 +7,7 @@
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
+ fill="currentColor"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue
index e628094..1f666d3 100644
--- a/src/components/TopNav/index.vue
+++ b/src/components/TopNav/index.vue
@@ -196,7 +196,7 @@
/* 鑳屾櫙鑹查殣钘� */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
- background-color: #ffffff !important;
+ background-color: #ffffff;
}
/* 鍥炬爣鍙抽棿璺� */
@@ -211,4 +211,6 @@
margin-left: 8px;
margin-top: 0px;
}
+
+
</style>
diff --git a/src/components/TreeSelect/index.vue b/src/components/TreeSelect/index.vue
deleted file mode 100644
index 82cafb7..0000000
--- a/src/components/TreeSelect/index.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<template>
- <div class="el-tree-select">
- <el-select
- style="width: 100%"
- v-model="valueId"
- ref="treeSelect"
- :filterable="true"
- :clearable="true"
- @clear="clearHandle"
- :filter-method="selectFilterData"
- :placeholder="placeholder"
- >
- <el-option :value="valueId" :label="valueTitle">
- <el-tree
- id="tree-option"
- ref="selectTree"
- :accordion="accordion"
- :data="options"
- :props="objMap"
- :node-key="objMap.value"
- :expand-on-click-node="false"
- :default-expanded-keys="defaultExpandedKey"
- :filter-node-method="filterNode"
- @node-click="handleNodeClick"
- ></el-tree>
- </el-option>
- </el-select>
- </div>
-</template>
-
-<script setup>
-
-const { proxy } = getCurrentInstance();
-
-const props = defineProps({
- /* 閰嶇疆椤� */
- objMap: {
- type: Object,
- default: () => {
- return {
- value: 'id', // ID瀛楁鍚�
- label: 'label', // 鏄剧ず鍚嶇О
- children: 'children' // 瀛愮骇瀛楁鍚�
- }
- }
- },
- /* 鑷姩鏀惰捣 */
- accordion: {
- type: Boolean,
- default: () => {
- return false
- }
- },
- /**褰撳墠鍙屽悜鏁版嵁缁戝畾鐨勫�� */
- value: {
- type: [String, Number],
- default: ''
- },
- /**褰撳墠鐨勬暟鎹� */
- options: {
- type: Array,
- default: () => []
- },
- /**杈撳叆妗嗗唴閮ㄧ殑鏂囧瓧 */
- placeholder: {
- type: String,
- default: ''
- }
-})
-
-const emit = defineEmits(['update:value']);
-
-const valueId = computed({
- get: () => props.value,
- set: (val) => {
- emit('update:value', val)
- }
-});
-const valueTitle = ref('');
-const defaultExpandedKey = ref([]);
-
-function initHandle() {
- nextTick(() => {
- const selectedValue = valueId.value;
- if(selectedValue !== null && typeof (selectedValue) !== 'undefined') {
- const node = proxy.$refs.selectTree.getNode(selectedValue)
- if (node) {
- valueTitle.value = node.data[props.objMap.label]
- proxy.$refs.selectTree.setCurrentKey(selectedValue) // 璁剧疆榛樿閫変腑
- defaultExpandedKey.value = [selectedValue] // 璁剧疆榛樿灞曞紑
- }
- } else {
- clearHandle()
- }
- })
-}
-function handleNodeClick(node) {
- valueTitle.value = node[props.objMap.label]
- valueId.value = node[props.objMap.value];
- defaultExpandedKey.value = [];
- proxy.$refs.treeSelect.blur()
- selectFilterData('')
-}
-function selectFilterData(val) {
- proxy.$refs.selectTree.filter(val)
-}
-function filterNode(value, data) {
- if (!value) return true
- return data[props.objMap['label']].indexOf(value) !== -1
-}
-function clearHandle() {
- valueTitle.value = ''
- valueId.value = ''
- defaultExpandedKey.value = [];
- clearSelected()
-}
-function clearSelected() {
- const allNode = document.querySelectorAll('#tree-option .el-tree-node')
- allNode.forEach((element) => element.classList.remove('is-current'))
-}
-
-onMounted(() => {
- initHandle()
-})
-
-watch(valueId, () => {
- initHandle();
-})
-</script>
-
-<style lang='scss' scoped>
-@import "@/assets/styles/variables.module.scss";
-.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
- padding: 0;
- background-color: #fff;
- height: auto;
-}
-
-.el-select-dropdown__item.selected {
- font-weight: normal;
-}
-
-ul li .el-tree .el-tree-node__content {
- height: auto;
- padding: 0 20px;
- box-sizing: border-box;
-}
-
-:deep(.el-tree-node__content:hover),
-:deep(.el-tree-node__content:active),
-:deep(.is-current > div:first-child),
-:deep(.el-tree-node__content:focus) {
- background-color: mix(#fff, $--color-primary, 90%);
- color: $--color-primary;
-}
-</style>
\ No newline at end of file
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index f669a6d..e0e2df8 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -18,6 +18,13 @@
<screenfull id="screenfull" class="right-menu-item hover-effect" />
+ <el-tooltip content="涓婚妯″紡" effect="dark" placement="bottom">
+ <div class="right-menu-item hover-effect theme-switch-wrapper" @click="toggleTheme">
+ <svg-icon v-if="settingsStore.isDark" icon-class="sunny" />
+ <svg-icon v-if="!settingsStore.isDark" icon-class="moon" />
+ </div>
+ </el-tooltip>
+
<el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
@@ -98,6 +105,10 @@
function setLayout() {
emits('setLayout');
}
+
+function toggleTheme() {
+ settingsStore.toggleTheme()
+}
</script>
<style lang='scss' scoped>
@@ -105,7 +116,7 @@
height: 50px;
overflow: hidden;
position: relative;
- background: #fff;
+ background: var(--navbar-bg);
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
@@ -150,7 +161,7 @@
padding: 0 8px;
height: 100%;
font-size: 18px;
- color: #5a5e66;
+ color: var(--navbar-text);
vertical-align: text-bottom;
&.hover-effect {
@@ -161,6 +172,19 @@
background: rgba(0, 0, 0, 0.025);
}
}
+
+ &.theme-switch-wrapper {
+ display: flex;
+ align-items: center;
+
+ svg {
+ transition: transform 0.3s;
+
+ &:hover {
+ transform: scale(1.15);
+ }
+ }
+ }
}
.avatar-container {
diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue
index 7164a17..7f2bcb7 100644
--- a/src/layout/components/Settings/index.vue
+++ b/src/layout/components/Settings/index.vue
@@ -149,13 +149,15 @@
<style lang='scss' scoped>
.setting-drawer-title {
margin-bottom: 12px;
- color: rgba(0, 0, 0, 0.85);
+ color: var(--el-text-color-primary, rgba(0, 0, 0, 0.85));
line-height: 22px;
font-weight: bold;
+
.drawer-title {
font-size: 14px;
}
}
+
.setting-drawer-block-checbox {
display: flex;
justify-content: flex-start;
@@ -174,13 +176,6 @@
height: 48px;
}
- .custom-img {
- width: 48px;
- height: 38px;
- border-radius: 5px;
- box-shadow: 1px 1px 2px #898484;
- }
-
.setting-drawer-block-checbox-selectIcon {
position: absolute;
top: 0;
@@ -197,7 +192,7 @@
}
.drawer-item {
- color: rgba(0, 0, 0, 0.65);
+ color: var(--el-text-color-regular, rgba(0, 0, 0, 0.65));
padding: 12px 0;
font-size: 14px;
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index 288e030..751b56e 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -1,22 +1,22 @@
<template>
- <div class="sidebar-logo-container" :class="{ 'collapse': collapse }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
+ <div class="sidebar-logo-container" :class="{ 'collapse': collapse }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
- <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
+ <h1 v-else class="sidebar-title">{{ title }}</h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
- <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
+ <h1 class="sidebar-title">{{ title }}</h1>
</router-link>
</transition>
</div>
</template>
<script setup>
-import variables from '@/assets/styles/variables.module.scss'
import logo from '@/assets/logo/logo.png'
import useSettingsStore from '@/store/modules/settings'
+import variables from '@/assets/styles/variables.module.scss'
defineProps({
collapse: {
@@ -28,9 +28,27 @@
const title = import.meta.env.VITE_APP_TITLE;
const settingsStore = useSettingsStore();
const sideTheme = computed(() => settingsStore.sideTheme);
+
+// 鑾峰彇Logo鑳屾櫙鑹�
+const getLogoBackground = computed(() => {
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-bg)';
+ }
+ return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg;
+});
+
+// 鑾峰彇Logo鏂囧瓧棰滆壊
+const getLogoTextColor = computed(() => {
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-text)';
+ }
+ return sideTheme.value === 'theme-dark' ? '#fff' : variables.menuLightText;
+});
</script>
<style lang="scss" scoped>
+@import '@/assets/styles/variables.module.scss';
+
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
@@ -45,7 +63,7 @@
width: 100%;
height: 50px;
line-height: 50px;
- background: #2b2f3a;
+ background: v-bind(getLogoBackground);
text-align: center;
overflow: hidden;
@@ -63,7 +81,7 @@
& .sidebar-title {
display: inline-block;
margin: 0;
- color: #fff;
+ color: v-bind(getLogoTextColor);
font-weight: 600;
line-height: 50px;
font-size: 14px;
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 646bb63..fd78773 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -1,16 +1,17 @@
<template>
- <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
+ <div :class="{ 'has-logo': showLogo }" class="sidebar-container">
<logo v-if="showLogo" :collapse="isCollapse" />
- <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
+ <el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
- :background-color="sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
- :text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
+ :background-color="getMenuBackground"
+ :text-color="getMenuTextColor"
:unique-opened="true"
:active-text-color="theme"
:collapse-transition="false"
mode="vertical"
+ :class="sideTheme"
>
<sidebar-item
v-for="(route, index) in sidebarRouters"
@@ -36,19 +37,68 @@
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
-const sidebarRouters = computed(() => permissionStore.sidebarRouters);
+const sidebarRouters = computed(() => permissionStore.sidebarRouters);
const showLogo = computed(() => settingsStore.sidebarLogo);
const sideTheme = computed(() => settingsStore.sideTheme);
const theme = computed(() => settingsStore.theme);
const isCollapse = computed(() => !appStore.sidebar.opened);
+// 鑾峰彇鑿滃崟鑳屾櫙鑹�
+const getMenuBackground = computed(() => {
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-bg)';
+ }
+ return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg;
+});
+
+// 鑾峰彇鑿滃崟鏂囧瓧棰滆壊
+const getMenuTextColor = computed(() => {
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-text)';
+ }
+ return sideTheme.value === 'theme-dark' ? variables.menuText : variables.menuLightText;
+});
+
const activeMenu = computed(() => {
const { meta, path } = route;
- // if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
-})
-
+});
</script>
+
+<style lang="scss" scoped>
+.sidebar-container {
+ background-color: v-bind(getMenuBackground);
+
+ .scrollbar-wrapper {
+ background-color: v-bind(getMenuBackground);
+ }
+
+ .el-menu {
+ border: none;
+ height: 100%;
+ width: 100% !important;
+
+ .el-menu-item, .el-sub-menu__title {
+ &:hover {
+ background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
+ }
+ }
+
+ .el-menu-item {
+ color: v-bind(getMenuTextColor);
+
+ &.is-active {
+ color: var(--menu-active-text, #409eff);
+ background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
+ }
+ }
+
+ .el-sub-menu__title {
+ color: v-bind(getMenuTextColor);
+ }
+ }
+}
+</style>
diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue
index 2cd6617..b8460a5 100644
--- a/src/layout/components/TagsView/index.vue
+++ b/src/layout/components/TagsView/index.vue
@@ -257,13 +257,14 @@
}
</script>
-<style lang='scss' scoped>
+<style lang="scss" scoped>
.tags-view-container {
height: 34px;
width: 100%;
- background: #fff;
- border-bottom: 1px solid #d8dce5;
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
+ background: var(--tags-bg, #fff);
+ border-bottom: 1px solid var(--tags-item-border, #d8dce5);
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
+
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
@@ -271,25 +272,29 @@
cursor: pointer;
height: 26px;
line-height: 26px;
- border: 1px solid #d8dce5;
- color: #495060;
- background: #fff;
+ border: 1px solid var(--tags-item-border, #d8dce5);
+ color: var(--tags-item-text, #495060);
+ background: var(--tags-item-bg, #fff);
padding: 0 8px;
font-size: 12px;
margin-left: 5px;
margin-top: 4px;
+
&:first-of-type {
margin-left: 15px;
}
+
&:last-of-type {
margin-right: 15px;
}
+
&.active {
background-color: #42b983;
color: #fff;
border-color: #42b983;
+
&::before {
- content: "";
+ content: '';
background: #fff;
display: inline-block;
width: 8px;
@@ -301,9 +306,10 @@
}
}
}
+
.contextmenu {
margin: 0;
- background: #fff;
+ background: var(--el-bg-color-overlay, #fff);
z-index: 3000;
position: absolute;
list-style-type: none;
@@ -311,14 +317,17 @@
border-radius: 4px;
font-size: 12px;
font-weight: 400;
- color: #333;
- box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
+ color: var(--tags-item-text, #333);
+ box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
+ border: 1px solid var(--el-border-color-light, #e4e7ed);
+
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
+
&:hover {
- background: #eee;
+ background: var(--tags-item-hover, #eee);
}
}
}
@@ -335,15 +344,17 @@
vertical-align: 2px;
border-radius: 50%;
text-align: center;
- transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+ transition: all .3s cubic-bezier(.645, .045, .355, 1);
transform-origin: 100% 50%;
+
&:before {
- transform: scale(0.6);
+ transform: scale(.6);
display: inline-block;
vertical-align: -3px;
}
+
&:hover {
- background-color: #b4bccc;
+ background-color: var(--tags-close-hover, #b4bccc);
color: #fff;
width: 12px !important;
height: 12px !important;
diff --git a/src/main.js b/src/main.js
index a7645fb..c01e80d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,6 +4,7 @@
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
+import 'element-plus/theme-chalk/dark/css-vars.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
import '@/assets/styles/index.scss' // global css
@@ -39,8 +40,6 @@
import ImageUpload from "@/components/ImageUpload"
// 鍥剧墖棰勮缁勪欢
import ImagePreview from "@/components/ImagePreview"
-// 鑷畾涔夋爲閫夋嫨缁勪欢
-import TreeSelect from '@/components/TreeSelect'
// 瀛楀吀鏍囩缁勪欢
import DictTag from '@/components/DictTag'
@@ -59,7 +58,6 @@
// 鍏ㄥ眬缁勪欢鎸傝浇
app.component('DictTag', DictTag)
app.component('Pagination', Pagination)
-app.component('TreeSelect', TreeSelect)
app.component('FileUpload', FileUpload)
app.component('ImageUpload', ImageUpload)
app.component('ImagePreview', ImagePreview)
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
index 3e41513..64b413a 100644
--- a/src/store/modules/settings.js
+++ b/src/store/modules/settings.js
@@ -1,5 +1,9 @@
import defaultSettings from '@/settings'
+import { useDark, useToggle } from '@vueuse/core'
import { useDynamicTitle } from '@/utils/dynamicTitle'
+
+const isDark = useDark()
+const toggleDark = useToggle(isDark)
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
@@ -17,7 +21,8 @@
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
- dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
+ dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
+ isDark: isDark.value
}),
actions: {
// 淇敼甯冨眬璁剧疆
@@ -30,7 +35,12 @@
// 璁剧疆缃戦〉鏍囬
setTitle(title) {
this.title = title
- useDynamicTitle();
+ useDynamicTitle()
+ },
+ // 鍒囨崲鏆楅粦妯″紡
+ toggleTheme() {
+ this.isDark = !this.isDark
+ toggleDark()
}
}
})
--
Gitblit v1.9.3