From a88eab39f6b2f5c33913d51fac4e885c052ed4a1 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 21 八月 2025 14:39:00 +0800
Subject: [PATCH] 整体样式修改
---
src/assets/styles/sidebar.scss | 67 --
src/layout/components/Sidebar/Logo.vue | 123 ++--
src/layout/components/Navbar.vue | 242 +++++-----
src/layout/index.vue | 108 ++--
src/settings.js | 2
src/layout/components/Sidebar/index.vue | 130 ++--
src/layout/components/TagsView/index.vue | 513 ++++++++++----------
src/store/modules/app.js | 2
src/assets/styles/variables.module.scss | 38
src/layout/components/Sidebar/SidebarItem.vue | 180 +++----
src/store/modules/settings.js | 2
11 files changed, 683 insertions(+), 724 deletions(-)
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index eb6a1c8..9a4c487 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -12,21 +12,18 @@
}
.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;
- top: 50px;
+ top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
-webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
- box-shadow: none;
- margin: 0 auto;
+ box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
// reset element-ui css
.horizontal-collapse-transition {
@@ -42,7 +39,7 @@
}
.el-scrollbar {
- height: 92%;
+ height: 100%;
}
&.has-logo {
@@ -54,29 +51,24 @@
.is-horizontal {
display: none;
}
+
a {
display: inline-block;
- width: 80px;
- height: 80px;
+ width: 100%;
overflow: hidden;
- margin-top: 20px;
}
-
.svg-icon {
- //margin-right: 16px;
+ margin-right: 16px;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
- padding: 0 20px !important;
}
.el-menu-item, .menu-title {
- line-height: 20px;
- font-size: 14px;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
@@ -89,69 +81,52 @@
// menu hover
.sub-menu-title-noDropdown,
.el-sub-menu__title {
- border-radius: 10px 10px 10px 10px;
&:hover {
- background-color: #ffffff !important;
- border-radius: 10px 10px 10px 10px;
- color: $base-menu-color-active !important;
+ background-color: rgba(0, 0, 0, 0.06) !important;
}
}
& .theme-dark .is-active > .el-sub-menu__title {
color: $base-menu-color-active !important;
}
- & .nest-menu > a {
- right: 20px;
- position: relative;
- }
- & .nest-menu> .el-sub-menu > .el-sub-menu__title {
- right: 20px;
- position: relative;
- }
+
& .nest-menu .el-sub-menu>.el-sub-menu__title,
& .el-sub-menu .el-menu-item {
+ min-width: $base-sidebar-width !important;
-
- height: 80px;
- min-width: 80px !important;
- border-radius: 10px 10px 10px 10px;
&:hover {
- background-color: #ffffff !important;
- border-radius: 10px 10px 10px 10px;
- color: $base-menu-color-active !important;
+ background-color: rgba(0, 0, 0, 0.06) !important;
}
}
& .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;
- border-radius: 10px 10px 10px 10px;
+
&:hover {
- background-color: #ffffff !important;
- border-radius: 10px 10px 10px 10px;
- color: $base-menu-color-active !important;
+ background-color: $base-sub-menu-hover !important;
}
}
}
.hideSidebar {
.sidebar-container {
- width: 120px !important;
+ width: 54px !important;
}
.main-container {
- margin-left: 120px;
+ margin-left: 54px;
}
.sub-menu-title-noDropdown {
- padding: 0 0 0 20px !important;
+ padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
- //margin-left: 20px;
+ margin-left: 20px;
}
}
}
@@ -163,7 +138,7 @@
padding: 0 !important;
.svg-icon {
- //margin-left: 20px;
+ margin-left: 20px;
}
}
@@ -226,21 +201,17 @@
// when menu collapsed
.el-menu--vertical {
- width: 120px !important; /* 璁剧疆涓�涓浐瀹氱殑瀹藉害 */
&>.el-menu {
.svg-icon {
- //margin-right: 16px;
+ margin-right: 16px;
}
}
.nest-menu .el-sub-menu>.el-sub-menu__title,
.el-menu-item {
- border-radius: 10px 10px 10px 10px;
&:hover {
// you can use $sub-menuHover
- background-color: #ffffff !important;
- border-radius: 10px 10px 10px 10px;
- color: $base-menu-color-active !important;
+ background-color: rgba(0, 0, 0, 0.06) !important;
}
}
diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss
index 678fe0d..bcc618e 100644
--- a/src/assets/styles/variables.module.scss
+++ b/src/assets/styles/variables.module.scss
@@ -9,30 +9,30 @@
$panGreen: #30B08F;
// 榛樿涓婚鍙橀噺
-$menuText: #ffffff;
-$menuActiveText: #165DFF;
-$menuBg: #165DFF;
-$menuHover: #ffffff;
+$menuText: #bfcbd9;
+$menuActiveText: #409eff;
+$menuBg: #304156;
+$menuHover: #263445;
// 娴呰壊涓婚theme-light
-$menuLightBg: #165DFF;
-$menuLightHover: #ffffff;
-$menuLightText: #ffffff;
-$menuLightActiveText: #165DFF;
+$menuLightBg: #ffffff;
+$menuLightHover: #f0f1f5;
+$menuLightText: #303133;
+$menuLightActiveText: #409EFF;
// 鍩虹鍙橀噺
-$base-sidebar-width: 120px;
-$sideBarWidth: 120px;
+$base-sidebar-width: 200px;
+$sideBarWidth: 200px;
// 鑿滃崟鏆楄壊鍙橀噺
$base-menu-color: #bfcbd9;
-$base-menu-color-active: #165DFF;
-$base-menu-background: #165DFF;
+$base-menu-color-active: #f4f4f5;
+$base-menu-background: #304156;
$base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover: #001528;
// 缁勪欢鍙橀噺
-$--color-primary: #165DFF;
+$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
@@ -71,10 +71,10 @@
--sidebar-bg: #{$menuBg};
--sidebar-text: #{$menuText};
--menu-hover: #{$menuHover};
-
+
--navbar-bg: #ffffff;
--navbar-text: #303133;
-
+
/* splitpanes default-theme 鍙橀噺 */
--splitpanes-default-bg: #ffffff;
@@ -119,7 +119,7 @@
--blockquote-bg: #1d1e1f;
--blockquote-border: #303030;
--blockquote-text: #d0d0d0;
-
+
/* Cron 鏃堕棿琛ㄨ揪寮� 妯″紡鍙橀噺 */
--cron-border: #303030;
@@ -127,7 +127,7 @@
--splitpanes-default-bg: #141414;
/* 渚ц竟鏍忚彍鍗曡鐩� */
- .sidebar-container {
+ .sidebar-container {
.el-menu-item, .menu-title {
color: var(--el-text-color-regular);
}
@@ -199,7 +199,7 @@
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;
@@ -211,7 +211,7 @@
border-left-color: var(--blockquote-border) !important;
color: var(--blockquote-text) !important;
}
-
+
/* 鏃堕棿琛ㄨ揪寮忔爣棰樻牱寮忚鐩� */
.popup-result .title {
background: var(--cron-border);
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index b6312ca..412dfce 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,13 +1,13 @@
<template>
<div class="navbar">
-<!-- <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />-->
-<!-- <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />-->
- <div v-if="sidebar.hide">
- <top-nav id="topmenu-container" class="topmenu-container" />
- </div>
- <div class="logo" v-if="!sidebar.hide">
- <img src="@/assets/logo/logo.png" alt=""/>
- </div>
+ <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+ <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
+<!-- <div v-if="sidebar.hide">-->
+<!-- <top-nav id="topmenu-container" class="topmenu-container" />-->
+<!-- </div>-->
+<!-- <div class="logo" v-if="!sidebar.hide">-->
+<!-- <img src="@/assets/logo/logo.png" alt=""/>-->
+<!-- </div>-->
<div class="right-menu">
<template v-if="appStore.device !== 'mobile'">
<header-search id="header-search" class="right-menu-item" />
@@ -23,9 +23,9 @@
<router-link to="/user/profile">
<el-dropdown-item>涓汉涓績</el-dropdown-item>
</router-link>
-<!-- <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">-->
-<!-- <span>甯冨眬璁剧疆</span>-->
-<!-- </el-dropdown-item>-->
+ <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
+ <span>甯冨眬璁剧疆</span>
+ </el-dropdown-item>
<el-dropdown-item divided command="logout">
<span>閫�鍑虹櫥褰�</span>
</el-dropdown-item>
@@ -135,116 +135,114 @@
<style lang='scss' scoped>
.navbar {
- height: 50px;
- overflow: hidden;
- position: fixed; /* 灏嗗ご閮ㄥ浐瀹� */
- top: 0; /* 鍦ㄩ《閮ㄥ浐瀹� */
- width: 100%; /* 瀹藉害100%锛岃鐩栨暣涓鍙� */
- //background-color: #f8f9fa; /* 璁剧疆鑳屾櫙棰滆壊锛屼互渚挎洿鏄庢樉鍦扮湅鍒版晥鏋� */
- z-index: 1000; /* 纭繚澶撮儴鍦ㄥ叾浠栧唴瀹逛箣涓� */
- background: var(--navbar-bg);
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
- display: flex;
- justify-content: space-between;
- padding: 0 20px;
-
- .logo {
- height: 50px;
- line-height: 50px;
- img {
- cursor: pointer;
- width: 146px;
- height: 46px;
- }
- }
-
- .breadcrumb-container {
- float: left;
- }
-
- .topmenu-container {
- position: absolute;
- }
-
- .errLog-container {
- display: inline-block;
- vertical-align: top;
- }
-
- .right-menu {
- float: right;
- height: 100%;
- line-height: 50px;
- display: flex;
-
- &:focus {
- outline: none;
- }
-
- .right-menu-item {
- display: inline-block;
- padding: 0 8px;
- height: 100%;
- font-size: 18px;
- color: #5a5e66;
- vertical-align: text-bottom;
-
- &.hover-effect {
- cursor: pointer;
- transition: background 0.3s;
-
- &:hover {
- 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 {
- margin-right: 0px;
- padding-right: 0px;
-
- .avatar-wrapper {
- margin-top: 10px;
- right: 5px;
- position: relative;
-
- .user-avatar {
- cursor: pointer;
- width: 30px;
- height: 30px;
- border-radius: 50%;
- }
-
- .user-nickname{
- position: relative;
- left: 5px;
- bottom: 10px;
- font-size: 14px;
- font-weight: bold;
- }
-
- i {
- cursor: pointer;
- position: absolute;
- right: -20px;
- top: 25px;
- font-size: 12px;
- }
- }
- }
- }
+ height: 50px;
+ overflow: hidden;
+ position: relative;
+ background: var(--navbar-bg);
+ box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+
+ .hamburger-container {
+ line-height: 46px;
+ height: 100%;
+ float: left;
+ cursor: pointer;
+ transition: background 0.3s;
+ -webkit-tap-highlight-color: transparent;
+
+ &:hover {
+ background: rgba(0, 0, 0, 0.025);
+ }
+ }
+
+ .breadcrumb-container {
+ float: left;
+ }
+
+ .topmenu-container {
+ position: absolute;
+ left: 50px;
+ }
+
+ .errLog-container {
+ display: inline-block;
+ vertical-align: top;
+ }
+
+ .right-menu {
+ float: right;
+ height: 100%;
+ line-height: 50px;
+ display: flex;
+ margin-right: 30px;
+
+ &:focus {
+ outline: none;
+ }
+
+ .right-menu-item {
+ display: inline-block;
+ padding: 0 8px;
+ height: 100%;
+ font-size: 18px;
+ color: #5a5e66;
+ vertical-align: text-bottom;
+
+ &.hover-effect {
+ cursor: pointer;
+ transition: background 0.3s;
+
+ &:hover {
+ 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 {
+ margin-right: 0px;
+ padding-right: 0px;
+
+ .avatar-wrapper {
+ margin-top: 10px;
+ right: 5px;
+ position: relative;
+
+ .user-avatar {
+ cursor: pointer;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ }
+
+ .user-nickname{
+ position: relative;
+ left: 5px;
+ bottom: 10px;
+ font-size: 14px;
+ font-weight: bold;
+ }
+
+ i {
+ cursor: pointer;
+ position: absolute;
+ right: -20px;
+ top: 25px;
+ font-size: 12px;
+ }
+ }
+ }
+ }
}
</style>
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index b2f1595..11bcd8c 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -1,16 +1,16 @@
<template>
- <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">{{ 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">{{ title }}</h1>
- </router-link>
- </transition>
- </div>
+ <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">{{ 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">{{ title }}</h1>
+ </router-link>
+ </transition>
+ </div>
</template>
<script setup>
@@ -19,10 +19,10 @@
import variables from '@/assets/styles/variables.module.scss'
defineProps({
- collapse: {
- type: Boolean,
- required: true
- }
+ collapse: {
+ type: Boolean,
+ required: true
+ }
})
const title = import.meta.env.VITE_APP_TITLE
@@ -31,18 +31,18 @@
// 鑾峰彇Logo鑳屾櫙鑹�
const getLogoBackground = computed(() => {
- if (settingsStore.isDark) {
- return 'var(--sidebar-bg)'
- }
- return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg
+ 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
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-text)'
+ }
+ return sideTheme.value === 'theme-dark' ? '#fff' : variables.menuLightText
})
</script>
@@ -50,50 +50,49 @@
@import '@/assets/styles/variables.module.scss';
.sidebarLogoFade-enter-active {
- transition: opacity 1.5s;
+ transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
- opacity: 0;
+ opacity: 0;
}
.sidebar-logo-container {
- position: relative;
- width: 100%;
- height: 50px;
- line-height: 50px;
- background: v-bind(getLogoBackground);
- text-align: center;
- overflow: hidden;
-
- & .sidebar-logo-link {
- height: 100%;
- width: 100%;
-
- & .sidebar-logo {
- width: 32px;
- height: 32px;
- vertical-align: middle;
- margin-right: 12px;
- }
-
- & .sidebar-title {
- display: inline-block;
- margin: 0;
- color: v-bind(getLogoTextColor);
- font-weight: 600;
- line-height: 50px;
- font-size: 14px;
- font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
- vertical-align: middle;
- }
- }
-
- &.collapse {
- .sidebar-logo {
- margin-right: 0px;
- }
- }
+ position: relative;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
+ background: v-bind(getLogoBackground);
+ text-align: center;
+ overflow: hidden;
+
+ & .sidebar-logo-link {
+ height: 100%;
+ width: 100%;
+
+ & .sidebar-logo {
+ height: 32px;
+ vertical-align: middle;
+ margin-right: 12px;
+ }
+
+ & .sidebar-title {
+ display: inline-block;
+ margin: 0;
+ color: v-bind(getLogoTextColor);
+ font-weight: 600;
+ line-height: 50px;
+ font-size: 14px;
+ font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
+ vertical-align: middle;
+ }
+ }
+
+ &.collapse {
+ .sidebar-logo {
+ margin-right: 0px;
+ }
+ }
}
</style>
\ No newline at end of file
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index 4884381..1a84a86 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -1,30 +1,30 @@
<template>
- <div v-if="!item.hidden">
- <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
- <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
- <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }" style="display: flex;flex-direction: column;justify-content: center;height: 80px;padding: 0;width: 80px">
- <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" style="width: 30px;height: 30px;margin-bottom: 6px"/>
- <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>
- </el-menu-item>
- </app-link>
- </template>
-
- <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
- <template v-if="item.meta" #title>
- <svg-icon :icon-class="item.meta && item.meta.icon" style="width: 30px;height: 30px;margin-bottom: 6px"/>
- <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title}}</span>
- </template>
-
- <sidebar-item
- v-for="(child, index) in item.children"
- :key="child.path + index"
- :is-nest="true"
- :item="child"
- :base-path="resolvePath(child.path)"
- class="nest-menu"
- />
- </el-sub-menu>
- </div>
+ <div v-if="!item.hidden">
+ <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
+ <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
+ <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
+ <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
+ <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>
+ </el-menu-item>
+ </app-link>
+ </template>
+
+ <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
+ <template v-if="item.meta" #title>
+ <svg-icon :icon-class="item.meta && item.meta.icon" />
+ <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
+ </template>
+
+ <sidebar-item
+ v-for="(child, index) in item.children"
+ :key="child.path + index"
+ :is-nest="true"
+ :item="child"
+ :base-path="resolvePath(child.path)"
+ class="nest-menu"
+ />
+ </el-sub-menu>
+ </div>
</template>
<script setup>
@@ -33,93 +33,71 @@
import { getNormalPath } from '@/utils/ruoyi'
const props = defineProps({
- // route object
- item: {
- type: Object,
- required: true
- },
- isNest: {
- type: Boolean,
- default: false
- },
- basePath: {
- type: String,
- default: ''
- }
+ // route object
+ item: {
+ type: Object,
+ required: true
+ },
+ isNest: {
+ type: Boolean,
+ default: false
+ },
+ basePath: {
+ type: String,
+ default: ''
+ }
})
const onlyOneChild = ref({})
function hasOneShowingChild(children = [], parent) {
- if (!children) {
- children = []
- }
- const showingChildren = children.filter(item => {
- if (item.hidden) {
- return false
- }
- onlyOneChild.value = item
- return true
- })
-
- // When there is only one child router, the child router is displayed by default
- if (showingChildren.length === 1) {
- return true
- }
-
- // Show parent if there are no child router to display
- if (showingChildren.length === 0) {
- onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
- return true
- }
-
- return false
+ if (!children) {
+ children = []
+ }
+ const showingChildren = children.filter(item => {
+ if (item.hidden) {
+ return false
+ }
+ onlyOneChild.value = item
+ return true
+ })
+
+ // When there is only one child router, the child router is displayed by default
+ if (showingChildren.length === 1) {
+ return true
+ }
+
+ // Show parent if there are no child router to display
+ if (showingChildren.length === 0) {
+ onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
+ return true
+ }
+
+ return false
}
function resolvePath(routePath, routeQuery) {
- if (isExternal(routePath)) {
- return routePath
- }
- if (isExternal(props.basePath)) {
- return props.basePath
- }
- if (routeQuery) {
- let query = JSON.parse(routeQuery)
- return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
- }
- return getNormalPath(props.basePath + '/' + routePath)
+ if (isExternal(routePath)) {
+ return routePath
+ }
+ if (isExternal(props.basePath)) {
+ return props.basePath
+ }
+ if (routeQuery) {
+ let query = JSON.parse(routeQuery)
+ return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
+ }
+ return getNormalPath(props.basePath + '/' + routePath)
}
function hasTitle(title){
- if (title.length > 5) {
- return title
- } else {
- return ""
- }
+ if (title.length > 5) {
+ return title
+ } else {
+ return ""
+ }
}
</script>
<style scoped>
-:deep(.el-sub-menu__title) {
- display: flex;
- flex-direction: column;
- justify-content: center;
- padding: 0 !important;
- height: 80px;
- margin-top: 20px;
-}
-:deep(.submenu-title-noDropdown) {
- padding: 0 !important;
-}
-:deep(.router-link-exact-active) {
- width: 80px;
- height: 80px;
- background: #FFFFFF;
- border-radius: 10px 10px 10px 10px;
-}
-:deep(.el-sub-menu__icon-arrow) {
- right: -12px !important;
- &:hover {
- color: #ffffff !important;
- }
-}
+
</style>
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 4d40e28..fe25d0f 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -1,25 +1,27 @@
<template>
- <div :class="{ 'has-logo': showLogo }" class="sidebar-container">
-<!-- <logo v-if="showLogo" :collapse="isCollapse" />-->
- <el-scrollbar wrap-class="scrollbar-wrapper">
- <el-menu
- :default-active="activeMenu"
- :background-color="getMenuBackground"
- :text-color="getMenuTextColor"
- :unique-opened="true"
- :active-text-color="theme"
- :collapse="false"
- mode="vertical"
- >
- <sidebar-item
- v-for="(route, index) in sidebarRouters"
- :key="route.path + index"
- :item="route"
- :base-path="route.path"
- />
- </el-menu>
- </el-scrollbar>
- </div>
+ <div :class="{ 'has-logo': showLogo }" class="sidebar-container">
+ <logo v-if="showLogo" :collapse="isCollapse" />
+ <el-scrollbar wrap-class="scrollbar-wrapper">
+ <el-menu
+ :default-active="activeMenu"
+ :collapse="isCollapse"
+ :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"
+ :key="route.path + index"
+ :item="route"
+ :base-path="route.path"
+ />
+ </el-menu>
+ </el-scrollbar>
+ </div>
</template>
<script setup>
@@ -39,62 +41,64 @@
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
+ 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
+ if (settingsStore.isDark) {
+ return 'var(--sidebar-text)'
+ }
+ return sideTheme.value === 'theme-dark' ? variables.menuText : variables.menuLightText
})
const activeMenu = computed(() => {
- const { meta, path } = route
- if (meta.activeMenu) {
- return meta.activeMenu
- }
- return path
+ const { meta, path } = route
+ 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);
- }
- }
+ 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 6321343..0eb2e41 100644
--- a/src/layout/components/TagsView/index.vue
+++ b/src/layout/components/TagsView/index.vue
@@ -1,44 +1,44 @@
<template>
- <div id="tags-view-container" class="tags-view-container">
- <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll">
- <router-link
- v-for="tag in visitedViews"
- :key="tag.path"
- :data-path="tag.path"
- :class="isActive(tag) ? 'active' : ''"
- :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
- class="tags-view-item"
- :style="activeStyle(tag)"
- @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
- @contextmenu.prevent="openMenu(tag, $event)"
- >
- {{ tag.title }}
- <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
+ <div id="tags-view-container" class="tags-view-container">
+ <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll">
+ <router-link
+ v-for="tag in visitedViews"
+ :key="tag.path"
+ :data-path="tag.path"
+ :class="isActive(tag) ? 'active' : ''"
+ :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
+ class="tags-view-item"
+ :style="activeStyle(tag)"
+ @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
+ @contextmenu.prevent="openMenu(tag, $event)"
+ >
+ {{ tag.title }}
+ <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
<close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
</span>
- </router-link>
- </scroll-pane>
- <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
- <li @click="refreshSelectedTag(selectedTag)">
- <refresh-right style="width: 1em; height: 1em;" /> 鍒锋柊椤甸潰
- </li>
- <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
- <close style="width: 1em; height: 1em;" /> 鍏抽棴褰撳墠
- </li>
- <li @click="closeOthersTags">
- <circle-close style="width: 1em; height: 1em;" /> 鍏抽棴鍏朵粬
- </li>
- <li v-if="!isFirstView()" @click="closeLeftTags">
- <back style="width: 1em; height: 1em;" /> 鍏抽棴宸︿晶
- </li>
- <li v-if="!isLastView()" @click="closeRightTags">
- <right style="width: 1em; height: 1em;" /> 鍏抽棴鍙充晶
- </li>
- <li @click="closeAllTags(selectedTag)">
- <circle-close style="width: 1em; height: 1em;" /> 鍏ㄩ儴鍏抽棴
- </li>
- </ul>
- </div>
+ </router-link>
+ </scroll-pane>
+ <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
+ <li @click="refreshSelectedTag(selectedTag)">
+ <refresh-right style="width: 1em; height: 1em;" /> 鍒锋柊椤甸潰
+ </li>
+ <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
+ <close style="width: 1em; height: 1em;" /> 鍏抽棴褰撳墠
+ </li>
+ <li @click="closeOthersTags">
+ <circle-close style="width: 1em; height: 1em;" /> 鍏抽棴鍏朵粬
+ </li>
+ <li v-if="!isFirstView()" @click="closeLeftTags">
+ <back style="width: 1em; height: 1em;" /> 鍏抽棴宸︿晶
+ </li>
+ <li v-if="!isLastView()" @click="closeRightTags">
+ <right style="width: 1em; height: 1em;" /> 鍏抽棴鍙充晶
+ </li>
+ <li @click="closeAllTags(selectedTag)">
+ <circle-close style="width: 1em; height: 1em;" /> 鍏ㄩ儴鍏抽棴
+ </li>
+ </ul>
+ </div>
</template>
<script setup>
@@ -64,293 +64,302 @@
const theme = computed(() => useSettingsStore().theme)
watch(route, () => {
- addTags()
- moveToCurrentTag()
+ addTags()
+ moveToCurrentTag()
})
watch(visible, (value) => {
- if (value) {
- document.body.addEventListener('click', closeMenu)
- } else {
- document.body.removeEventListener('click', closeMenu)
- }
+ if (value) {
+ document.body.addEventListener('click', closeMenu)
+ } else {
+ document.body.removeEventListener('click', closeMenu)
+ }
})
onMounted(() => {
- initTags()
- addTags()
+ initTags()
+ addTags()
})
function isActive(r) {
- return r.path === route.path
+ return r.path === route.path
}
function activeStyle(tag) {
- if (!isActive(tag)) return {}
- return {
- "background-color": theme.value,
- "border-color": theme.value
- }
+ if (!isActive(tag)) return {}
+ return {
+ "background-color": theme.value,
+ "border-color": theme.value
+ }
}
function isAffix(tag) {
- return tag.meta && tag.meta.affix
+ return tag.meta && tag.meta.affix
}
function isFirstView() {
- try {
- return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath
- } catch (err) {
- return false
- }
+ try {
+ return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath
+ } catch (err) {
+ return false
+ }
}
function isLastView() {
- try {
- return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath
- } catch (err) {
- return false
- }
+ try {
+ return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath
+ } catch (err) {
+ return false
+ }
}
function filterAffixTags(routes, basePath = '') {
- let tags = []
- routes.forEach(route => {
- if (route.meta && route.meta.affix) {
- const tagPath = getNormalPath(basePath + '/' + route.path)
- tags.push({
- fullPath: tagPath,
- path: tagPath,
- name: route.name,
- meta: { ...route.meta }
- })
- }
- if (route.children) {
- const tempTags = filterAffixTags(route.children, route.path)
- if (tempTags.length >= 1) {
- tags = [...tags, ...tempTags]
- }
- }
- })
- return tags
+ let tags = []
+ routes.forEach(route => {
+ if (route.meta && route.meta.affix) {
+ const tagPath = getNormalPath(basePath + '/' + route.path)
+ tags.push({
+ fullPath: tagPath,
+ path: tagPath,
+ name: route.name,
+ meta: { ...route.meta }
+ })
+ }
+ if (route.children) {
+ const tempTags = filterAffixTags(route.children, route.path)
+ if (tempTags.length >= 1) {
+ tags = [...tags, ...tempTags]
+ }
+ }
+ })
+ return tags
}
function initTags() {
- const res = filterAffixTags(routes.value)
- affixTags.value = res
- for (const tag of res) {
- // Must have tag name
- if (tag.name) {
- useTagsViewStore().addVisitedView(tag)
- }
- }
+ const res = filterAffixTags(routes.value)
+ affixTags.value = res
+ for (const tag of res) {
+ // Must have tag name
+ if (tag.name) {
+ useTagsViewStore().addVisitedView(tag)
+ }
+ }
}
function addTags() {
- const { name } = route
- if (name) {
- useTagsViewStore().addView(route)
- }
+ const { name } = route
+ if (name) {
+ useTagsViewStore().addView(route)
+ }
}
function moveToCurrentTag() {
- nextTick(() => {
- for (const r of visitedViews.value) {
- if (r.path === route.path) {
- scrollPaneRef.value.moveToTarget(r)
- // when query is different then update
- if (r.fullPath !== route.fullPath) {
- useTagsViewStore().updateVisitedView(route)
- }
- }
- }
- })
+ nextTick(() => {
+ for (const r of visitedViews.value) {
+ if (r.path === route.path) {
+ scrollPaneRef.value.moveToTarget(r)
+ // when query is different then update
+ if (r.fullPath !== route.fullPath) {
+ useTagsViewStore().updateVisitedView(route)
+ }
+ }
+ }
+ })
}
function refreshSelectedTag(view) {
- proxy.$tab.refreshPage(view)
- if (route.meta.link) {
- useTagsViewStore().delIframeView(route)
- }
+ proxy.$tab.refreshPage(view)
+ if (route.meta.link) {
+ useTagsViewStore().delIframeView(route)
+ }
}
function closeSelectedTag(view) {
- proxy.$tab.closePage(view).then(({ visitedViews }) => {
- if (isActive(view)) {
- toLastView(visitedViews, view)
- }
- })
+ proxy.$tab.closePage(view).then(({ visitedViews }) => {
+ if (isActive(view)) {
+ toLastView(visitedViews, view)
+ }
+ })
}
function closeRightTags() {
- proxy.$tab.closeRightPage(selectedTag.value).then(visitedViews => {
- if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
- toLastView(visitedViews)
- }
- })
+ proxy.$tab.closeRightPage(selectedTag.value).then(visitedViews => {
+ if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
+ toLastView(visitedViews)
+ }
+ })
}
function closeLeftTags() {
- proxy.$tab.closeLeftPage(selectedTag.value).then(visitedViews => {
- if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
- toLastView(visitedViews)
- }
- })
+ proxy.$tab.closeLeftPage(selectedTag.value).then(visitedViews => {
+ if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
+ toLastView(visitedViews)
+ }
+ })
}
function closeOthersTags() {
- router.push(selectedTag.value).catch(() => { })
- proxy.$tab.closeOtherPage(selectedTag.value).then(() => {
- moveToCurrentTag()
- })
+ router.push(selectedTag.value).catch(() => { })
+ proxy.$tab.closeOtherPage(selectedTag.value).then(() => {
+ moveToCurrentTag()
+ })
}
function closeAllTags(view) {
- proxy.$tab.closeAllPage().then(({ visitedViews }) => {
- if (affixTags.value.some(tag => tag.path === route.path)) {
- return
- }
- toLastView(visitedViews, view)
- })
+ proxy.$tab.closeAllPage().then(({ visitedViews }) => {
+ if (affixTags.value.some(tag => tag.path === route.path)) {
+ return
+ }
+ toLastView(visitedViews, view)
+ })
}
function toLastView(visitedViews, view) {
- const latestView = visitedViews.slice(-1)[0]
- if (latestView) {
- router.push(latestView.fullPath)
- } else {
- // now the default is to redirect to the home page if there is no tags-view,
- // you can adjust it according to your needs.
- if (view.name === 'Dashboard') {
- // to reload home page
- router.replace({ path: '/redirect' + view.fullPath })
- } else {
- router.push('/')
- }
- }
+ const latestView = visitedViews.slice(-1)[0]
+ if (latestView) {
+ router.push(latestView.fullPath)
+ } else {
+ // now the default is to redirect to the home page if there is no tags-view,
+ // you can adjust it according to your needs.
+ if (view.name === 'Dashboard') {
+ // to reload home page
+ router.replace({ path: '/redirect' + view.fullPath })
+ } else {
+ router.push('/')
+ }
+ }
}
function openMenu(tag, e) {
- const menuMinWidth = 105
- const offsetLeft = proxy.$el.getBoundingClientRect().left // container margin left
- const offsetWidth = proxy.$el.offsetWidth // container width
- const maxLeft = offsetWidth - menuMinWidth // left boundary
- const l = e.clientX - offsetLeft + 15 // 15: margin right
-
- if (l > maxLeft) {
- left.value = maxLeft
- } else {
- left.value = l
- }
-
- top.value = e.clientY
- visible.value = true
- selectedTag.value = tag
+ const menuMinWidth = 105
+ const offsetLeft = proxy.$el.getBoundingClientRect().left // container margin left
+ const offsetWidth = proxy.$el.offsetWidth // container width
+ const maxLeft = offsetWidth - menuMinWidth // left boundary
+ const l = e.clientX - offsetLeft + 15 // 15: margin right
+
+ if (l > maxLeft) {
+ left.value = maxLeft
+ } else {
+ left.value = l
+ }
+
+ top.value = e.clientY
+ visible.value = true
+ selectedTag.value = tag
}
function closeMenu() {
- visible.value = false
+ visible.value = false
}
function handleScroll() {
- closeMenu()
+ closeMenu()
}
</script>
<style lang="scss" scoped>
.tags-view-container {
- height: 34px;
- width: 100%;
- position: fixed; /* 灏嗗ご閮ㄥ浐瀹� */
- top: 50px; /* 鍦ㄩ《閮ㄥ浐瀹� */
- z-index: 1000; /* 纭繚澶撮儴鍦ㄥ叾浠栧唴瀹逛箣涓� */
- background: #fff;
- box-shadow: none;
-
- .tags-view-wrapper {
- .tags-view-item {
- display: inline-block;
- position: relative;
- cursor: pointer;
- height: 30px;
- line-height: 26px;
- //border: 1px solid var(--tags-item-border, #d8dce5);
- color: var(--tags-item-text, #495060);
- background: var(--tags-item-bg, #fff);
- padding: 2px 16px;
- font-size: 12px;
- //margin-left: 5px;
- margin-top: 4px;
-
- &:first-of-type {
- margin-left: 15px;
- }
-
- &:last-of-type {
- margin-right: 15px;
- }
-
- &.active {
- border-radius: 10px 10px 0px 0px;
- background-color: #F7F7F7 !important;
- color: #165DFF;
- }
- }
- }
-
- .contextmenu {
- margin: 0;
- background: var(--el-bg-color-overlay, #fff);
- z-index: 3000;
- position: absolute;
- list-style-type: none;
- padding: 5px 0;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 400;
- 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: var(--tags-item-hover, #eee);
- }
- }
- }
+ height: 34px;
+ width: 100%;
+ 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;
+ position: relative;
+ cursor: pointer;
+ height: 26px;
+ line-height: 26px;
+ 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: '';
+ background: #fff;
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ position: relative;
+ margin-right: 5px;
+ }
+ }
+ }
+ }
+
+ .contextmenu {
+ margin: 0;
+ background: var(--el-bg-color-overlay, #fff);
+ z-index: 3000;
+ position: absolute;
+ list-style-type: none;
+ padding: 5px 0;
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 400;
+ 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: var(--tags-item-hover, #eee);
+ }
+ }
+ }
}
</style>
<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
- .tags-view-item {
- .el-icon-close {
- width: 16px;
- height: 16px;
- vertical-align: 2px;
- border-radius: 50%;
- text-align: center;
- transition: all .3s cubic-bezier(.645, .045, .355, 1);
- transform-origin: 100% 50%;
-
- &:before {
- transform: scale(.6);
- display: inline-block;
- vertical-align: -3px;
- }
-
- &:hover {
- background-color: var(--tags-close-hover, #b4bccc);
- color: #fff;
- width: 12px !important;
- height: 12px !important;
- }
- }
- }
+ .tags-view-item {
+ .el-icon-close {
+ width: 16px;
+ height: 16px;
+ vertical-align: 2px;
+ border-radius: 50%;
+ text-align: center;
+ transition: all .3s cubic-bezier(.645, .045, .355, 1);
+ transform-origin: 100% 50%;
+
+ &:before {
+ transform: scale(.6);
+ display: inline-block;
+ vertical-align: -3px;
+ }
+
+ &:hover {
+ background-color: var(--tags-close-hover, #b4bccc);
+ color: #fff;
+ width: 12px !important;
+ height: 12px !important;
+ }
+ }
+ }
}
</style>
\ No newline at end of file
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 60738ba..b317aad 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -1,16 +1,16 @@
<template>
- <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
- <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
- <navbar @setLayout="setLayout" />
- <sidebar v-if="!sidebar.hide" class="sidebar-container" />
- <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
- <div :class="{ 'fixed-header': fixedHeader }">
- <tags-view v-if="needTagsView" />
- </div>
- <app-main />
- <settings ref="settingRef" />
- </div>
- </div>
+ <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
+ <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
+ <sidebar v-if="!sidebar.hide" class="sidebar-container" />
+ <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
+ <div :class="{ 'fixed-header': fixedHeader }">
+ <navbar @setLayout="setLayout" />
+ <tags-view v-if="needTagsView" />
+ </div>
+ <app-main />
+ <settings ref="settingRef" />
+ </div>
+ </div>
</template>
<script setup>
@@ -29,84 +29,84 @@
const fixedHeader = computed(() => settingsStore.fixedHeader)
const classObj = computed(() => ({
- hideSidebar: !sidebar.value.opened,
- openSidebar: sidebar.value.opened,
- withoutAnimation: sidebar.value.withoutAnimation,
- mobile: device.value === 'mobile'
+ hideSidebar: !sidebar.value.opened,
+ openSidebar: sidebar.value.opened,
+ withoutAnimation: sidebar.value.withoutAnimation,
+ mobile: device.value === 'mobile'
}))
const { width, height } = useWindowSize()
const WIDTH = 992 // refer to Bootstrap's responsive design
watch(() => device.value, () => {
- if (device.value === 'mobile' && sidebar.value.opened) {
- useAppStore().closeSideBar({ withoutAnimation: false })
- }
+ if (device.value === 'mobile' && sidebar.value.opened) {
+ useAppStore().closeSideBar({ withoutAnimation: false })
+ }
})
watchEffect(() => {
- if (width.value - 1 < WIDTH) {
- useAppStore().toggleDevice('mobile')
- useAppStore().closeSideBar({ withoutAnimation: true })
- } else {
- useAppStore().toggleDevice('desktop')
- }
+ if (width.value - 1 < WIDTH) {
+ useAppStore().toggleDevice('mobile')
+ useAppStore().closeSideBar({ withoutAnimation: true })
+ } else {
+ useAppStore().toggleDevice('desktop')
+ }
})
function handleClickOutside() {
- useAppStore().closeSideBar({ withoutAnimation: false })
+ useAppStore().closeSideBar({ withoutAnimation: false })
}
const settingRef = ref(null)
function setLayout() {
- settingRef.value.openSetting()
+ settingRef.value.openSetting()
}
</script>
<style lang="scss" scoped>
- @import "@/assets/styles/mixin.scss";
- @import "@/assets/styles/variables.module.scss";
+@import "@/assets/styles/mixin.scss";
+@import "@/assets/styles/variables.module.scss";
.app-wrapper {
- @include clearfix;
- position: relative;
- height: 100%;
- width: 100%;
-
- &.mobile.openSidebar {
- position: fixed;
- top: 0;
- }
+ @include clearfix;
+ position: relative;
+ height: 100%;
+ width: 100%;
+
+ &.mobile.openSidebar {
+ position: fixed;
+ top: 0;
+ }
}
.drawer-bg {
- background: #000;
- opacity: 0.3;
- width: 100%;
- top: 0;
- height: 100%;
- position: absolute;
- z-index: 999;
+ background: #000;
+ opacity: 0.3;
+ width: 100%;
+ top: 0;
+ height: 100%;
+ position: absolute;
+ z-index: 999;
}
.fixed-header {
- position: fixed;
- top: 0;
- right: 0;
- z-index: 9;
- width: calc(100% - #{$base-sidebar-width});
- transition: width 0.28s;
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: 9;
+ width: calc(100% - #{$base-sidebar-width});
+ transition: width 0.28s;
}
.hideSidebar .fixed-header {
- width: calc(100% - 120px);
+ width: calc(100% - 54px);
}
.sidebarHide .fixed-header {
- width: 100%;
+ width: 100%;
}
.mobile .fixed-header {
- width: 100%;
+ width: 100%;
}
</style>
\ No newline at end of file
diff --git a/src/settings.js b/src/settings.js
index b5d3962..2fc67a5 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -37,7 +37,7 @@
/**
* 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
*/
- dynamicTitle: false,
+ dynamicTitle: true,
/**
* @type {string | array} 'production' | ['production', 'development']
diff --git a/src/store/modules/app.js b/src/store/modules/app.js
index cd4824b..9a92dd1 100644
--- a/src/store/modules/app.js
+++ b/src/store/modules/app.js
@@ -5,7 +5,7 @@
{
state: () => ({
sidebar: {
- opened: true,
+ opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false,
hide: false
},
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
index 51aaeb1..194d678 100644
--- a/src/store/modules/settings.js
+++ b/src/store/modules/settings.js
@@ -14,7 +14,7 @@
{
state: () => ({
title: '',
- theme: storageSetting.theme || '#165DFF',
+ theme: storageSetting.theme || '#409EFF',
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
--
Gitblit v1.9.3