Spaces:
Sleeping
Sleeping
| <template> | |
| <div class="pc-aside"> | |
| <!-- Logo 区域 --> | |
| <div class="pc-aside__logo"> | |
| <img :src="logo" alt="Cloud Saver Logo" class="logo__image" /> | |
| <h1 class="logo__title">Cloud Saver</h1> | |
| </div> | |
| <!-- 菜单区域 --> | |
| <el-menu | |
| :default-active="currentMenu?.index || '1'" | |
| :default-openeds="currentMenuOpen" | |
| class="pc-aside__menu" | |
| > | |
| <template v-for="menu in menuList" :key="menu.index"> | |
| <!-- 子菜单 --> | |
| <el-sub-menu v-if="menu.children" :index="menu.index"> | |
| <template #title> | |
| <el-icon><component :is="menu.icon" /></el-icon> | |
| <span>{{ menu.title }}</span> | |
| </template> | |
| <el-menu-item | |
| v-for="child in menu.children" | |
| :key="child.index" | |
| :index="child.index" | |
| @click="handleMenuClick(child)" | |
| > | |
| <span>{{ child.title }}</span> | |
| </el-menu-item> | |
| </el-sub-menu> | |
| <!-- 普通菜单项 --> | |
| <el-menu-item | |
| v-else | |
| :index="menu.index" | |
| :disabled="menu.disabled" | |
| @click="handleMenuClick(menu)" | |
| > | |
| <el-icon><component :is="menu.icon" /></el-icon> | |
| <span>{{ menu.title }}</span> | |
| </el-menu-item> | |
| </template> | |
| </el-menu> | |
| <!-- GitHub 链接 --> | |
| <div class="pc-aside__footer"> | |
| <a :href="PROJECT_GITHUB" target="_blank" rel="noopener noreferrer" class="github-link"> | |
| <svg | |
| height="20" | |
| aria-hidden="true" | |
| viewBox="0 0 24 24" | |
| version="1.1" | |
| width="20" | |
| class="github-icon" | |
| > | |
| <path | |
| fill="currentColor" | |
| d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z" | |
| /> | |
| </svg> | |
| <span>GitHub</span> | |
| <span class="version">v{{ pkg.version }}</span> | |
| </a> | |
| </div> | |
| </div> | |
| </template> | |
| <script setup lang="ts"> | |
| import { computed } from "vue"; | |
| import { useRouter, useRoute } from "vue-router"; | |
| import { Search, Film, Setting, Link } from "@element-plus/icons-vue"; | |
| import logo from "@/assets/images/logo.png"; | |
| import { PROJECT_GITHUB } from "@/constants/project"; | |
| import pkg from "../../package.json"; | |
| // 类型定义 | |
| interface MenuItem { | |
| index: string; | |
| title: string; | |
| icon?: typeof Search | typeof Film | typeof Setting | typeof Link; | |
| router?: string; | |
| children?: MenuItem[]; | |
| disabled?: boolean; | |
| } | |
| // 路由相关 | |
| const router = useRouter(); | |
| const route = useRoute(); | |
| // 菜单配置 | |
| const menuList: MenuItem[] = [ | |
| { | |
| index: "1", | |
| title: "资源搜索", | |
| icon: Search, | |
| router: "/resource", | |
| }, | |
| { | |
| index: "2", | |
| title: "豆瓣榜单", | |
| icon: Film, | |
| children: [ | |
| { | |
| index: "2-1", | |
| title: "热门电影", | |
| router: "/douban?type=movie", | |
| }, | |
| { | |
| index: "2-2", | |
| title: "热门电视剧", | |
| router: "/douban?type=tv", | |
| }, | |
| { | |
| index: "2-3", | |
| title: "最新电影", | |
| router: "/douban?type=movie&tag=最新", | |
| }, | |
| { | |
| index: "2-4", | |
| title: "热门综艺", | |
| router: "/douban?type=tv&tag=综艺", | |
| }, | |
| ], | |
| }, | |
| { | |
| index: "3", | |
| title: "设置", | |
| icon: Setting, | |
| router: "/setting", | |
| disabled: false, | |
| }, | |
| { | |
| index: "4", | |
| title: "鸣谢", | |
| icon: Link, | |
| router: "/thanks", | |
| }, | |
| ]; | |
| // 计算当前激活的菜单 | |
| const currentMenu = computed(() => { | |
| const flatMenus = menuList.reduce<MenuItem[]>((acc, menu) => { | |
| if (!menu.children) { | |
| acc.push(menu); | |
| } else { | |
| acc.push(...menu.children); | |
| } | |
| return acc; | |
| }, []); | |
| return flatMenus.find((menu) => menu.router === decodeURIComponent(route.fullPath)); | |
| }); | |
| // 计算当前展开的子菜单 | |
| const currentMenuOpen = computed(() => { | |
| if (currentMenu.value?.index.includes("-")) { | |
| return [currentMenu.value.index.split("-")[0]]; | |
| } | |
| return []; | |
| }); | |
| // 菜单点击处理 | |
| const handleMenuClick = (menu: MenuItem) => { | |
| if (menu.router) { | |
| router.push(menu.router); | |
| } | |
| }; | |
| </script> | |
| <style lang="scss" scoped> | |
| @import "@/styles/common.scss"; | |
| .pc-aside { | |
| height: 100%; | |
| background: var(--theme-card-bg); | |
| border-right: 1px solid rgba(0, 0, 0, 0.1); | |
| // Logo 区域 | |
| &__logo { | |
| @include flex-center; | |
| padding: 24px 16px; | |
| gap: 12px; | |
| .logo__image { | |
| width: 32px; | |
| height: 32px; | |
| object-fit: contain; | |
| } | |
| .logo__title { | |
| margin: 0; | |
| font-size: 18px; | |
| font-weight: 600; | |
| color: var(--theme-text-primary); | |
| @include text-overflow; | |
| } | |
| } | |
| // 菜单区域 | |
| &__menu { | |
| border-right: none; | |
| background: transparent; | |
| :deep(.el-menu-item) { | |
| height: 48px; | |
| line-height: 48px; | |
| color: var(--theme-text-regular); | |
| &.is-active { | |
| color: var(--theme-primary); | |
| background: rgba(0, 102, 204, 0.1); | |
| } | |
| &:hover { | |
| color: var(--theme-primary); | |
| background: rgba(0, 102, 204, 0.05); | |
| } | |
| } | |
| :deep(.el-sub-menu) { | |
| .el-sub-menu__title { | |
| color: var(--theme-text-regular); | |
| &:hover { | |
| color: var(--theme-primary); | |
| background: rgba(0, 102, 204, 0.05); | |
| } | |
| } | |
| } | |
| :deep(.el-icon) { | |
| font-size: 18px; | |
| margin-right: 12px; | |
| color: inherit; | |
| } | |
| } | |
| // GitHub 链接区域 | |
| &__footer { | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| right: 0; | |
| padding: 16px; | |
| border-top: 1px solid rgba(0, 0, 0, 0.1); | |
| background: var(--theme-card-bg); | |
| .github-link { | |
| @include flex-center; | |
| gap: 8px; | |
| padding: 12px; | |
| color: var(--theme-text-regular); | |
| text-decoration: none; | |
| border-radius: var(--theme-radius); | |
| transition: var(--theme-transition); | |
| .github-icon { | |
| font-size: 20px; | |
| transition: var(--theme-transition); | |
| } | |
| .version { | |
| font-size: 12px; | |
| opacity: 0.7; | |
| margin-left: 4px; | |
| } | |
| &:hover { | |
| color: var(--theme-primary); | |
| background: rgba(0, 102, 204, 0.05); | |
| transform: translateY(-1px); | |
| .github-icon { | |
| transform: scale(1.1); | |
| } | |
| .version { | |
| opacity: 1; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // 自定义滚动条 | |
| .pc-aside__menu { | |
| height: calc(100vh - 80px - 69px); // 减去 logo 高度和 footer 高度 | |
| overflow-y: auto; | |
| &::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| &::-webkit-scrollbar-thumb { | |
| background: rgba(0, 0, 0, 0.2); | |
| border-radius: 3px; | |
| &:hover { | |
| background: rgba(0, 0, 0, 0.3); | |
| } | |
| } | |
| &::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| } | |
| </style> | |