LoongPanel-Asp/web/components/shell/SideBar.vue

188 lines
3.9 KiB
Vue
Raw Permalink Normal View History

2024-06-22 10:54:02 +08:00
<script lang="ts" setup>
2024-07-22 18:41:15 +08:00
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
import {type MenuOption, NIcon} from "naive-ui";
2024-07-23 12:51:10 +08:00
import { LayoutGrid,Computer,Cpu,Cctv,UserRoundCog,Goal,Settings,LogOut,PanelLeftClose,PanelLeftOpen,SquareTerminal } from 'lucide-vue-next';
2024-07-22 18:41:15 +08:00
import type {Component} from "vue";
import { useLoadingBar } from 'naive-ui'
2024-06-22 10:54:02 +08:00
const {$gsap} = useNuxtApp()
const mainLayoutStore = useMainLayoutStore()
2024-07-22 18:41:15 +08:00
const loadingBar = useLoadingBar()
const collapsed=ref<boolean>(false)
const activeKey= ref<string | null>(null);
function renderIcon(icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
const menuOptions: MenuOption[] = [
2024-06-22 10:54:02 +08:00
{
2024-07-22 18:41:15 +08:00
label: '系统概览',
key: 'home',
icon:renderIcon(LayoutGrid)
2024-06-22 10:54:02 +08:00
},
2024-07-02 14:28:15 +08:00
{
2024-07-22 18:41:15 +08:00
label: '主机监测',
key: 'host',
icon:renderIcon(Computer),
children: [
2024-07-23 12:51:10 +08:00
{
label: '终端',
key: 'terminal',
icon:renderIcon(SquareTerminal)
},
2024-07-22 18:41:15 +08:00
{
label: 'CPU',
key: 'host/cpu',
icon:renderIcon(Cpu)
}
]
2024-07-02 14:28:15 +08:00
},
2024-07-22 18:41:15 +08:00
{
label: '用户监测',
key: 'serverUser/all',
icon:renderIcon(Cctv)
},
{
label:'账号管理',
key: 'user',
icon:renderIcon(UserRoundCog)
},
{
label: '巡检记录',
key: 'inspectionRecords',
icon:renderIcon(Goal)
},
{
label: '系统设置',
key: 'Settings',
icon:renderIcon(Settings)
},
{
label: '退出登录',
key: 'Exit',
icon:renderIcon(LogOut)
2024-06-22 10:54:02 +08:00
}
2024-07-22 18:41:15 +08:00
]
2024-07-23 12:51:10 +08:00
defineExpose({
menuOptions
})
2024-07-22 18:41:15 +08:00
watch(()=>activeKey.value,async (newValue)=>{
loadingBar.start()
await navigateTo("/"+newValue)
loadingBar.finish()
2024-06-22 10:54:02 +08:00
})
2024-07-02 14:28:15 +08:00
2024-06-22 10:54:02 +08:00
</script>
<template>
<section class="sidebar-layout">
2024-07-22 18:41:15 +08:00
<transition name="fade" mode="out-in">
<div v-if="!collapsed" class="header">
<n-image
width="45"
src="/Square310x310Logo.png"
/>
<h1>龙盾云御</h1>
2024-06-22 10:54:02 +08:00
</div>
2024-07-22 18:41:15 +08:00
<div v-else class="header">
<n-image
width="45"
src="/Square310x310Logo.png"
/>
<h1 v-if="!collapsed">龙盾云御</h1>
2024-06-22 10:54:02 +08:00
</div>
2024-07-22 18:41:15 +08:00
</transition>
<n-layout has-sider>
<n-layout-sider
collapse-mode="width"
:collapsed-width="64"
:collapsed="collapsed"
@collapse="collapsed = true"
@expand="collapsed = false"
:width="200"
2024-07-22 21:05:18 +08:00
:inverted="$colorMode.value == 'dark'"
2024-07-22 18:41:15 +08:00
>
<n-menu
2024-07-22 21:05:18 +08:00
:inverted="$colorMode.value == 'dark'"
2024-07-22 18:41:15 +08:00
:collapsed="collapsed"
v-model:value="activeKey"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
</n-layout>
2024-07-22 21:05:18 +08:00
2024-07-22 18:41:15 +08:00
<div class="bottom">
<PanelLeftOpen v-if="collapsed" @click="collapsed=false" />
<PanelLeftClose v-else @click="collapsed=true" />
2024-06-22 10:54:02 +08:00
</div>
</section>
</template>
<style lang="scss" scoped>
@import "base";
.sidebar-layout {
display: flex;
grid-area: sidebar;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
2024-07-22 18:41:15 +08:00
gap: $gap;
2024-07-22 21:05:18 +08:00
border-right: $border;
2024-06-22 10:54:02 +08:00
background: $light-bg-color;
position: relative;
2024-07-02 14:28:15 +08:00
*{
@include SC_Font
}
2024-06-22 10:54:02 +08:00
.dark-mode & {
background: $dark-bg-color;
2024-07-22 21:05:18 +08:00
border-right: $border-dark;
2024-06-22 10:54:02 +08:00
}
}
2024-07-22 18:41:15 +08:00
.fade-enter-active {
transition: opacity 0.5s ease;
2024-06-22 10:54:02 +08:00
}
2024-07-22 18:41:15 +08:00
.fade-leave-active{
transition: opacity 0.05s ease;
2024-06-22 10:54:02 +08:00
}
2024-07-22 18:41:15 +08:00
/* 进入开始状态和离开结束状态 */
.fade-enter-from, .fade-leave-to {
opacity: 0;
scale: 0;
2024-06-22 10:54:02 +08:00
}
2024-07-22 18:41:15 +08:00
.header {
2024-07-22 21:05:18 +08:00
height: 62px;
2024-06-22 10:54:02 +08:00
display: flex;
width: 100%;
2024-07-22 18:41:15 +08:00
align-items: center;
justify-content: center;
2024-06-22 10:54:02 +08:00
gap: $gap;
2024-07-22 21:05:18 +08:00
2024-07-22 18:41:15 +08:00
h1{
font-size: 30px;
font-weight: 600;
}
2024-06-22 10:54:02 +08:00
}
2024-07-22 18:41:15 +08:00
.bottom{
2024-07-22 21:05:18 +08:00
height: 50px;
2024-06-22 10:54:02 +08:00
display: flex;
align-items: center;
2024-07-22 18:41:15 +08:00
width: 100%;
padding: 20px;
2024-07-22 21:05:18 +08:00
border-top: $border;
.dark-mode & {border-top: $border-dark;}
}
.n-layout{
background: unset;
}
.n-layout-sider{
background: unset;
2024-06-22 10:54:02 +08:00
}
</style>