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