feat: sidebar layout with dark mode support
Restore full Element Plus sidebar with collapsible navigation, mobile drawer, and dark mode CSS variables integration
This commit is contained in:
parent
f5c6a6991b
commit
9a76c657af
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="layout-container">
|
<el-container class="layout-container">
|
||||||
<el-aside :width="collapsed ? '64px' : '200px'" class="sidebar desktop-only">
|
<el-aside :width="collapsed ? '64px' : '200px'" class="sidebar desktop-only transition-base">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<h2 v-if="!collapsed">运动会记分板</h2>
|
<h2 v-if="!collapsed" class="slide-down-enter">运动会记分板</h2>
|
||||||
<el-icon v-else :size="24"><Trophy /></el-icon>
|
<el-icon v-else :size="24" class="slide-down-enter"><Trophy /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-toggle">
|
<div class="sidebar-toggle">
|
||||||
<el-button text @click="toggleCollapse" size="small">
|
<el-button text @click="toggleCollapse" size="small" class="rotate-icon">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<ArrowLeft v-if="!collapsed" />
|
<ArrowLeft v-if="!collapsed" />
|
||||||
<ArrowRight v-else />
|
<ArrowRight v-else />
|
||||||
@ -19,9 +19,10 @@
|
|||||||
:collapse="collapsed"
|
:collapse="collapsed"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
>
|
>
|
||||||
|
<template v-for="item in menuItems" :key="item.path || item.label">
|
||||||
|
<!-- Regular menu item -->
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
v-for="item in menuItems"
|
v-if="!item.children"
|
||||||
:key="item.path"
|
|
||||||
:index="item.path"
|
:index="item.path"
|
||||||
@click="onMenuClick(item.path)"
|
@click="onMenuClick(item.path)"
|
||||||
>
|
>
|
||||||
@ -29,6 +30,27 @@
|
|||||||
<span>{{ item.label }}</span>
|
<span>{{ item.label }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
|
<!-- Submenu with children -->
|
||||||
|
<el-sub-menu
|
||||||
|
v-else
|
||||||
|
:index="item.label"
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
<el-icon><component :is="item.icon" /></el-icon>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item
|
||||||
|
v-for="child in item.children"
|
||||||
|
:key="child.path"
|
||||||
|
:index="child.path"
|
||||||
|
@click="onMenuClick(child.path)"
|
||||||
|
>
|
||||||
|
<el-icon><component :is="child.icon" /></el-icon>
|
||||||
|
<span>{{ child.label }}</span>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-sub-menu v-if="hasAdminMenu" index="admin">
|
<el-sub-menu v-if="hasAdminMenu" index="admin">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon><Setting /></el-icon>
|
<el-icon><Setting /></el-icon>
|
||||||
@ -54,6 +76,12 @@
|
|||||||
<h3>运动会管理系统</h3>
|
<h3>运动会管理系统</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
<el-button text @click="toggleDark()" class="theme-toggle-btn">
|
||||||
|
<el-icon>
|
||||||
|
<Sunny v-if="isDark" />
|
||||||
|
<Moon v-else />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
<el-dropdown v-if="currentUser" @command="handleUserCommand">
|
<el-dropdown v-if="currentUser" @command="handleUserCommand">
|
||||||
<span class="user-info">
|
<span class="user-info">
|
||||||
<el-avatar :size="32">
|
<el-avatar :size="32">
|
||||||
@ -86,7 +114,7 @@
|
|||||||
direction="ltr"
|
direction="ltr"
|
||||||
size="70%"
|
size="70%"
|
||||||
:with-header="false"
|
:with-header="false"
|
||||||
class="mobile-only"
|
class="mobile-only drawer-transition"
|
||||||
>
|
>
|
||||||
<div class="drawer-logo">
|
<div class="drawer-logo">
|
||||||
<h2>运动会记分板</h2>
|
<h2>运动会记分板</h2>
|
||||||
@ -95,9 +123,10 @@
|
|||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
class="drawer-menu"
|
class="drawer-menu"
|
||||||
>
|
>
|
||||||
|
<template v-for="item in menuItems" :key="item.path || item.label">
|
||||||
|
<!-- Regular menu item -->
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
v-for="item in menuItems"
|
v-if="!item.children"
|
||||||
:key="item.path"
|
|
||||||
:index="item.path"
|
:index="item.path"
|
||||||
@click="onMenuClick(item.path, true)"
|
@click="onMenuClick(item.path, true)"
|
||||||
>
|
>
|
||||||
@ -105,6 +134,27 @@
|
|||||||
<span>{{ item.label }}</span>
|
<span>{{ item.label }}</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
|
||||||
|
<!-- Submenu with children -->
|
||||||
|
<el-sub-menu
|
||||||
|
v-else
|
||||||
|
:index="item.label"
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
<el-icon><component :is="item.icon" /></el-icon>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item
|
||||||
|
v-for="child in item.children"
|
||||||
|
:key="child.path"
|
||||||
|
:index="child.path"
|
||||||
|
@click="onMenuClick(child.path, true)"
|
||||||
|
>
|
||||||
|
<el-icon><component :is="child.icon" /></el-icon>
|
||||||
|
<span>{{ child.label }}</span>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-sub-menu v-if="hasAdminMenu" index="admin">
|
<el-sub-menu v-if="hasAdminMenu" index="admin">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon><Setting /></el-icon>
|
<el-icon><Setting /></el-icon>
|
||||||
@ -122,7 +172,7 @@
|
|||||||
</el-menu>
|
</el-menu>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<el-dialog v-model="showLoginDialog" title="登录" width="400px">
|
<el-dialog v-model="showLoginDialog" title="登录" width="400px" class="dialog-zoom">
|
||||||
<el-form :model="loginForm" :rules="loginRules" ref="loginFormRef">
|
<el-form :model="loginForm" :rules="loginRules" ref="loginFormRef">
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input
|
<el-input
|
||||||
@ -150,7 +200,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { HomeFilled, Trophy, UserFilled, Edit, DataLine, Menu, Setting, Key, ArrowLeft, ArrowRight, ArrowDown } from '@element-plus/icons-vue'
|
import { HomeFilled, Trophy, UserFilled, Edit, DataLine, Menu, Setting, Key, ArrowLeft, ArrowRight, ArrowDown, LocationFilled, Sunny, Moon } from '@element-plus/icons-vue'
|
||||||
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const activeMenu = computed(() => route.path)
|
const activeMenu = computed(() => route.path)
|
||||||
@ -159,6 +211,22 @@ const showLoginDialog = ref(false)
|
|||||||
const logging = ref(false)
|
const logging = ref(false)
|
||||||
const loginFormRef = ref()
|
const loginFormRef = ref()
|
||||||
|
|
||||||
|
// 使用 VueUse 的 useDark 管理暗色模式 - SSR safe
|
||||||
|
const isDark = ref(false)
|
||||||
|
const toggleDark = ref(() => {})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const dark = useDark({
|
||||||
|
selector: 'html',
|
||||||
|
attribute: 'class',
|
||||||
|
valueDark: 'dark',
|
||||||
|
valueLight: '',
|
||||||
|
storageKey: 'theme',
|
||||||
|
})
|
||||||
|
isDark.value = dark
|
||||||
|
toggleDark.value = useToggle(dark)
|
||||||
|
})
|
||||||
|
|
||||||
const collapsed = ref(false)
|
const collapsed = ref(false)
|
||||||
const currentUser = ref<any>(null)
|
const currentUser = ref<any>(null)
|
||||||
const hasAdminMenu = computed(() => currentUser.value?.role === 'admin')
|
const hasAdminMenu = computed(() => currentUser.value?.role === 'admin')
|
||||||
@ -175,11 +243,18 @@ const loginRules = {
|
|||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ path: '/', label: '首页', icon: HomeFilled },
|
{ path: '/', label: '首页', icon: HomeFilled },
|
||||||
|
{
|
||||||
|
label: '比赛管理',
|
||||||
|
icon: Trophy,
|
||||||
|
children: [
|
||||||
{ path: '/events', label: '比赛项目', icon: Trophy },
|
{ path: '/events', label: '比赛项目', icon: Trophy },
|
||||||
{ path: '/teams', label: '队伍管理', icon: UserFilled },
|
{ path: '/teams', label: '队伍管理', icon: UserFilled },
|
||||||
{ path: '/results', label: '成绩录入', icon: Edit },
|
{ path: '/results', label: '成绩录入', icon: Edit },
|
||||||
{ path: '/scoreboard', label: '记分板', icon: DataLine }
|
{ path: '/scoreboard', label: '记分板', icon: DataLine }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{ path: '/checkins', label: '机位打卡', icon: LocationFilled }
|
||||||
|
]
|
||||||
|
|
||||||
const toggleCollapse = () => {
|
const toggleCollapse = () => {
|
||||||
collapsed.value = !collapsed.value
|
collapsed.value = !collapsed.value
|
||||||
@ -243,9 +318,12 @@ onMounted(() => {
|
|||||||
if (savedUser) {
|
if (savedUser) {
|
||||||
currentUser.value = JSON.parse(savedUser)
|
currentUser.value = JSON.parse(savedUser)
|
||||||
}
|
}
|
||||||
|
// 主题切换由 VueUse useDark 自动处理
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.layout-container {
|
.layout-container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -256,73 +334,213 @@ onMounted(() => {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 侧边栏 - 始终使用深色背景 */
|
||||||
.sidebar {
|
.sidebar {
|
||||||
background-color: #304156;
|
background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-header-bg) 100%);
|
||||||
color: #fff;
|
color: var(--sidebar-text);
|
||||||
transition: width 0.3s;
|
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 56px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #2b3a4a;
|
background-color: var(--sidebar-header-bg);
|
||||||
|
border-bottom: 1px rgba(255, 255, 255, 0.05);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo h2 {
|
.logo h2 {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 16px;
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-toggle {
|
.sidebar-toggle {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding: 4px 8px;
|
padding: 8px 12px;
|
||||||
border-bottom: 1px solid #263445;
|
border-bottom: 1px rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rotate-icon {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-icon:hover {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 菜单样式 */
|
||||||
.sidebar-menu {
|
.sidebar-menu {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
background-color: #304156;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-menu:not(.el-menu--collapse) {
|
.sidebar-menu:not(.el-menu--collapse) {
|
||||||
width: 200px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-menu .el-menu-item,
|
.sidebar-menu .el-menu-item,
|
||||||
.sidebar-menu .el-sub-menu__title {
|
.sidebar-menu .el-sub-menu__title {
|
||||||
color: #bfcbd9;
|
color: var(--sidebar-text);
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
margin: 4px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-menu .el-menu-item:hover,
|
.sidebar-menu .el-menu-item:hover,
|
||||||
.sidebar-menu .el-sub-menu__title:hover,
|
.sidebar-menu .el-sub-menu__title:hover {
|
||||||
|
background-color: var(--sidebar-hover-bg);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-menu .el-menu-item.is-active,
|
.sidebar-menu .el-menu-item.is-active,
|
||||||
.sidebar-menu .el-sub-menu .el-menu-item.is-active {
|
.sidebar-menu .el-sub-menu .el-menu-item.is-active {
|
||||||
background-color: #263445;
|
background-color: var(--sidebar-active-bg);
|
||||||
color: #409eff;
|
color: var(--sidebar-active-text);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item.is-active::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 3px;
|
||||||
|
height: 24px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 子菜单样式 */
|
||||||
|
.sidebar-menu .el-sub-menu .el-menu-item {
|
||||||
|
padding-left: 20px !important;
|
||||||
|
margin: 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 菜单图标 */
|
||||||
|
.sidebar-menu .el-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Staggered animation for menu items */
|
||||||
|
.sidebar-menu .el-menu-item:nth-child(1),
|
||||||
|
.sidebar-menu .el-sub-menu:nth-child(1) {
|
||||||
|
animation-delay: 0.05s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item:nth-child(2),
|
||||||
|
.sidebar-menu .el-sub-menu:nth-child(2) {
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item:nth-child(3),
|
||||||
|
.sidebar-menu .el-sub-menu:nth-child(3) {
|
||||||
|
animation-delay: 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item:nth-child(4),
|
||||||
|
.sidebar-menu .el-sub-menu:nth-child(4) {
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item:nth-child(5),
|
||||||
|
.sidebar-menu .el-sub-menu:nth-child(5) {
|
||||||
|
animation-delay: 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-in-left {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-20px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item:hover,
|
||||||
|
.sidebar-menu .el-sub-menu__title:hover {
|
||||||
|
background-color: var(--sidebar-hover-bg);
|
||||||
|
color: #fff;
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item.is-active,
|
||||||
|
.sidebar-menu .el-sub-menu .el-menu-item.is-active {
|
||||||
|
background-color: var(--sidebar-active-bg);
|
||||||
|
color: var(--sidebar-active-text);
|
||||||
|
font-weight: 500;
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-menu .el-menu-item.is-active::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 3px;
|
||||||
|
height: 24px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 子菜单样式 */
|
||||||
|
.sidebar-menu .el-sub-menu .el-menu-item {
|
||||||
|
padding-left: 20px !important;
|
||||||
|
margin: 2px 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 菜单图标 - 确保垂直居中 */
|
||||||
|
.sidebar-menu .el-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 子菜单箭头对齐 */
|
||||||
|
.sidebar-menu .el-sub-menu__title .el-sub-menu__icon-arrow {
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background-color: #fff;
|
background-color: var(--header-bg);
|
||||||
border-bottom: 1px solid #e6e6e6;
|
border-bottom: 1px solid var(--header-border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 20px;
|
padding: 0 24px;
|
||||||
height: 56px;
|
height: 60px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-left {
|
.header-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-right {
|
.header-right {
|
||||||
@ -332,7 +550,9 @@ onMounted(() => {
|
|||||||
|
|
||||||
.header h3 {
|
.header h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #303133;
|
color: var(--header-text);
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
@ -340,37 +560,78 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info:hover {
|
||||||
|
background-color: var(--sidebar-hover-bg);
|
||||||
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
color: #303133;
|
color: var(--header-text);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle-btn {
|
||||||
|
margin-right: 12px;
|
||||||
|
color: var(--header-text);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle-btn:hover {
|
||||||
|
background-color: var(--sidebar-hover-bg) !important;
|
||||||
|
color: #fff;
|
||||||
|
transform: rotate(30deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
background-color: #f0f2f5;
|
background-color: var(--main-bg);
|
||||||
padding: 20px;
|
padding: 24px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
animation: fade-in 0.4s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 移动端抽屉 */
|
||||||
.drawer-logo {
|
.drawer-logo {
|
||||||
height: 56px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #2b3a4a;
|
background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-header-bg) 100%);
|
||||||
color: #fff;
|
border-bottom: 1px rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.drawer-logo h2 {
|
.drawer-logo h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drawer-menu {
|
.drawer-menu {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
background-color: var(--sidebar-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-menu .el-menu-item,
|
||||||
|
.drawer-menu .el-sub-menu__title,
|
||||||
|
.drawer-menu .el-sub-menu .el-menu-item {
|
||||||
|
color: var(--sidebar-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-menu .el-menu-item:hover,
|
||||||
|
.drawer-menu .el-sub-menu__title:hover,
|
||||||
|
.drawer-menu .el-menu-item.is-active,
|
||||||
|
.drawer-menu .el-sub-menu .el-menu-item.is-active {
|
||||||
|
background-color: var(--sidebar-hover-bg);
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop-only {
|
.desktop-only {
|
||||||
@ -385,7 +646,7 @@ onMounted(() => {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 768px) {
|
||||||
.desktop-only {
|
.desktop-only {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -399,17 +660,17 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
padding: 0 12px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
padding: 12px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
background-color: #fff;
|
background-color: var(--footer-bg);
|
||||||
border-top: 1px solid #e6e6e6;
|
border-top: 1px solid var(--footer-border);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -420,7 +681,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.footer p {
|
.footer p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #909399;
|
color: var(--footer-text);
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user