208 lines
5.2 KiB
Vue
208 lines
5.2 KiB
Vue
<!-- src/components/Sidebar.vue -->
|
|
<template>
|
|
<div class="sidebar">
|
|
<a-menu
|
|
mode="inline"
|
|
:selected-keys="selectedKeys"
|
|
:open-keys="openKeys"
|
|
@click="handleMenuClick"
|
|
theme="light"
|
|
class="custom-menu"
|
|
>
|
|
<template v-for="item in menuItems" :key="item.path">
|
|
<!-- 有子菜单的项 -->
|
|
<a-sub-menu v-if="item.children && item.children.length" :key="item.path">
|
|
<template #title>
|
|
<span class="menu-item-content">
|
|
<span class="icon">
|
|
<component :is="item.icon" />
|
|
</span>
|
|
<span class="menu-text">{{ item.name }}</span>
|
|
</span>
|
|
</template>
|
|
<a-menu-item v-for="child in item.children" :key="child.path">
|
|
<router-link :to="child.path" class="submenu-item">
|
|
<span class="menu-text">{{ child.name }}</span>
|
|
</router-link>
|
|
</a-menu-item>
|
|
</a-sub-menu>
|
|
|
|
<!-- 没有子菜单的项 -->
|
|
<a-menu-item v-else :key="item.path">
|
|
<router-link :to="item.path" class="menu-item-content">
|
|
<span class="icon">
|
|
<component :is="item.icon" />
|
|
</span>
|
|
<span class="menu-text">{{ item.name }}</span>
|
|
</router-link>
|
|
</a-menu-item>
|
|
</template>
|
|
</a-menu>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { HomeOutlined,FolderOpenOutlined,ConsoleSqlOutlined ,GlobalOutlined,LaptopOutlined,MoneyCollectOutlined,TeamOutlined} from '@ant-design/icons-vue'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
interface MenuItem {
|
|
path: string
|
|
name: string
|
|
icon: any
|
|
children?: { path: string; name: string }[]
|
|
}
|
|
|
|
const menuItems: MenuItem[] = [
|
|
{
|
|
path: '/contract',
|
|
name: '费用中心',
|
|
icon: MoneyCollectOutlined,
|
|
children: [
|
|
{ path: '/contract', name: '合同' },
|
|
{ path: '/controlPanel/fee/bill', name: '账单' }
|
|
]
|
|
},
|
|
{
|
|
path: '/controlPanel/account',
|
|
name: '我的账号',
|
|
icon: TeamOutlined,
|
|
children: [
|
|
{ path: '/accountSecurity', name: '账号安全' },
|
|
{ path: '/accountHistory', name: '访问记录' },
|
|
// { path: '/controlPanel/account/security', name: '安全设置' }
|
|
]
|
|
},
|
|
{ path: '/controlPanel/container', name: '容器实例', icon: ConsoleSqlOutlined },
|
|
// { path: '/controlPanel/fileStore', name: '文件存储', icon: FolderOpenOutlined },
|
|
{ path: '/controlPanel/image', name: '镜像', icon: GlobalOutlined },
|
|
{ path: '/controlPanel/publicData', name: '公开数据', icon: LaptopOutlined },
|
|
|
|
]
|
|
|
|
const selectedKeys = computed(() => [route.path])
|
|
|
|
const openKeys = computed(() => {
|
|
const keys: string[] = []
|
|
if (route.path.startsWith('/controlPanel/fee')) keys.push('/controlPanel/fee')
|
|
if (route.path.startsWith('/controlPanel/account')) keys.push('/controlPanel/account')
|
|
return keys
|
|
})
|
|
|
|
const handleMenuClick = ({ key }: { key: string }) => {
|
|
router.push(key)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.sidebar {
|
|
width: 240px;
|
|
height: 100vh;
|
|
background: #fff;
|
|
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
|
|
padding-top:30px;
|
|
/* overflow-y: auto; */
|
|
}
|
|
|
|
.menu-item-content {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.icon {
|
|
margin-right: 12px; /* 增加图标和文字的间距 */
|
|
width: 20px;
|
|
text-align: center;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 16px; /* 图标大小 */
|
|
}
|
|
|
|
.menu-text {
|
|
font-size: 14px; /* 文字大小 */
|
|
font-weight: 500; /* 中等字重 */
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.submenu-item {
|
|
display: block;
|
|
width: 100%;
|
|
padding-left: 32px; /* 子菜单项缩进 */
|
|
}
|
|
|
|
/* 自定义菜单样式 */
|
|
:deep(.custom-menu.ant-menu) {
|
|
font-size: 14px;
|
|
border: none;
|
|
}
|
|
|
|
:deep(.custom-menu.ant-menu-inline) {
|
|
background: transparent;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item) {
|
|
height: 48px; /* 增加菜单项高度 */
|
|
line-height: 48px;
|
|
margin: 0;
|
|
border-radius: 0;
|
|
width: 100%;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item:not(:last-child)) {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-submenu-title) {
|
|
height: 48px; /* 增加子菜单标题高度 */
|
|
line-height: 48px;
|
|
padding-right: 12px !important;
|
|
border-radius: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-submenu .ant-menu-item) {
|
|
height: 40px; /* 子菜单项稍矮一些 */
|
|
line-height: 40px;
|
|
padding-left: 48px !important; /* 子菜单项缩进 */
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item-selected) {
|
|
background-color: #e6f7ff; /* 选中背景色 */
|
|
border-right: 3px solid #1890ff; /* 选中指示条 */
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item:active),
|
|
:deep(.custom-menu .ant-menu-submenu-title:active) {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item a) {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-submenu-arrow) {
|
|
color: rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
/* 鼠标悬停效果 */
|
|
:deep(.custom-menu .ant-menu-item:hover),
|
|
:deep(.custom-menu .ant-menu-submenu-title:hover) {
|
|
background-color: #f5f5f5;
|
|
color: #1890ff;
|
|
}
|
|
|
|
:deep(.custom-menu .ant-menu-item:hover .icon),
|
|
:deep(.custom-menu .ant-menu-submenu-title:hover .icon) {
|
|
color: #1890ff;
|
|
}
|
|
</style> |