148 lines
3.9 KiB
Vue
Raw Normal View History

<script lang="ts" setup>
import { useDevice } from "@/composables/useDevice"
import { useLayoutMode } from "@/composables/useLayoutMode"
import { useAppStore } from "@/pinia/stores/app"
import { usePermissionStore } from "@/pinia/stores/permission"
import { useSettingsStore } from "@/pinia/stores/settings"
import { getCssVar } from "@/utils/css"
2024-11-18 19:40:44 +08:00
import { computed } from "vue"
import { useRoute } from "vue-router"
import Logo from "../Logo/index.vue"
import SidebarItem from "./SidebarItem.vue"
2022-05-25 21:53:38 +08:00
const v3SidebarMenuBgColor = getCssVar("--v3-sidebar-menu-bg-color")
const v3SidebarMenuTextColor = getCssVar("--v3-sidebar-menu-text-color")
const v3SidebarMenuActiveTextColor = getCssVar("--v3-sidebar-menu-active-text-color")
2024-02-06 13:39:56 +08:00
const { isMobile } = useDevice()
2024-02-06 15:25:16 +08:00
const { isLeft, isTop } = useLayoutMode()
const route = useRoute()
2022-08-24 16:52:01 +08:00
const appStore = useAppStore()
const permissionStore = usePermissionStore()
const settingsStore = useSettingsStore()
2022-08-25 16:26:28 +08:00
const activeMenu = computed(() => {
2023-06-15 13:42:58 +08:00
const {
meta: { activeMenu },
path
} = route
2024-11-18 19:40:44 +08:00
return activeMenu || path
})
2024-11-18 19:40:44 +08:00
const noHiddenRoutes = computed(() => permissionStore.routes.filter(item => !item.meta?.hidden))
2024-02-06 13:39:56 +08:00
const isCollapse = computed(() => !appStore.sidebar.opened)
2024-02-06 15:25:16 +08:00
const isLogo = computed(() => isLeft.value && settingsStore.showLogo)
const backgroundColor = computed(() => (isLeft.value ? v3SidebarMenuBgColor : undefined))
const textColor = computed(() => (isLeft.value ? v3SidebarMenuTextColor : undefined))
const activeTextColor = computed(() => (isLeft.value ? v3SidebarMenuActiveTextColor : undefined))
2023-07-18 11:14:07 +08:00
const sidebarMenuItemHeight = computed(() => {
2024-02-06 15:25:16 +08:00
return !isTop.value ? "var(--v3-sidebar-menu-item-height)" : "var(--v3-navigationbar-height)"
2023-07-18 11:14:07 +08:00
})
const sidebarMenuHoverBgColor = computed(() => {
2024-02-06 15:25:16 +08:00
return !isTop.value ? "var(--v3-sidebar-menu-hover-bg-color)" : "transparent"
2023-07-18 11:14:07 +08:00
})
const tipLineWidth = computed(() => {
2024-02-06 15:25:16 +08:00
return !isTop.value ? "2px" : "0px"
2023-07-18 11:14:07 +08:00
})
</script>
<template>
2023-07-06 13:02:52 +08:00
<div :class="{ 'has-logo': isLogo }">
<Logo v-if="isLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
2023-07-18 11:14:07 +08:00
:collapse="isCollapse && !isTop"
:background-color="backgroundColor"
:text-color="textColor"
:active-text-color="activeTextColor"
2022-08-25 16:26:28 +08:00
:unique-opened="true"
:collapse-transition="false"
2023-07-18 11:14:07 +08:00
:mode="isTop && !isMobile ? 'horizontal' : 'vertical'"
>
2024-11-18 19:40:44 +08:00
<SidebarItem
v-for="noHiddenRoute in noHiddenRoutes"
:key="noHiddenRoute.path"
:item="noHiddenRoute"
:base-path="noHiddenRoute.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<style lang="scss" scoped>
%tip-line {
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
2023-07-18 11:14:07 +08:00
width: v-bind(tipLineWidth);
height: 100%;
2022-05-25 21:53:38 +08:00
background-color: var(--v3-sidebar-menu-tip-line-bg-color);
}
}
.has-logo {
.el-scrollbar {
height: calc(100% - var(--v3-header-height));
}
}
2022-08-25 16:26:28 +08:00
.el-scrollbar {
height: 100%;
:deep(.scrollbar-wrapper) {
2022-08-25 16:26:28 +08:00
// 限制水平宽度
2024-11-21 11:03:40 +08:00
overflow-x: hidden;
2022-08-25 16:26:28 +08:00
}
// 滚动条
:deep(.el-scrollbar__bar) {
2022-08-25 16:26:28 +08:00
&.is-horizontal {
// 隐藏水平滚动条
display: none;
}
}
}
.el-menu {
border: none;
2024-11-21 11:03:40 +08:00
width: 100%;
}
.el-menu--horizontal {
height: v-bind(sidebarMenuItemHeight);
}
:deep(.el-menu-item),
:deep(.el-sub-menu__title),
2023-07-18 11:14:07 +08:00
:deep(.el-sub-menu .el-menu-item),
:deep(.el-menu--horizontal .el-menu-item) {
height: v-bind(sidebarMenuItemHeight);
line-height: v-bind(sidebarMenuItemHeight);
2022-09-30 16:58:37 +08:00
&.is-active,
&:hover {
2023-07-18 11:14:07 +08:00
background-color: v-bind(sidebarMenuHoverBgColor);
}
}
2023-07-18 11:14:07 +08:00
:deep(.el-sub-menu) {
&.is-active {
2023-08-16 14:48:50 +08:00
> .el-sub-menu__title {
2024-11-21 11:03:40 +08:00
color: v-bind(activeTextColor);
2023-07-18 11:14:07 +08:00
}
}
}
:deep(.el-menu-item.is-active) {
@extend %tip-line;
}
.el-menu--collapse {
:deep(.el-sub-menu.is-active) {
.el-sub-menu__title {
@extend %tip-line;
}
}
}
</style>