IntelliClass_FE/components/app/NavMain.vue
2025-04-19 01:32:50 +08:00

127 lines
3.7 KiB
Vue

<script setup lang="ts">
import { ChevronRight } from 'lucide-vue-next'
import type { SidebarNavItem } from './Sidebar.vue'
defineProps<{
nav: {
label?: string
items: SidebarNavItem[]
}[]
}>()
</script>
<template>
<SidebarGroup
v-for="group in nav"
:key="group.label"
>
<SidebarGroupLabel v-if="group.label">
{{ group.label }}
</SidebarGroupLabel>
<SidebarMenu>
<Collapsible
v-for="item in group.items"
:key="item.title"
as-child
:default-open="item.isActive"
class="group/collapsible"
>
<SidebarMenuItem>
<CollapsibleTrigger as-child>
<!-- 有跳转链接 -->
<NuxtLink
v-if="item.url"
v-slot="{ isActive, href, navigate }"
class="py-5"
:to="item.url"
custom
>
<SidebarMenuButton
as="a"
:tooltip="item.title"
:is-active="isActive"
:href
:target="item.isExternal ? '_blank' : undefined"
@click="navigate"
>
<!-- 图标名 -->
<Icon
v-if="item.icon && typeof item.icon === 'string'"
:name="item.icon"
class="!size-6"
/>
<!-- 图标组件 -->
<component
:is="item.icon"
v-else
class="!size-6"
/>
<span>{{ item.title }}</span>
<!-- 有子项目 -->
<ChevronRight
v-if="item.items"
class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
/>
<!-- 外部链接 -->
<Icon
v-if="item.isExternal"
name="tabler:external-link"
class="ml-auto !size-4 opacity-50"
size="16px"
/>
</SidebarMenuButton>
</NuxtLink>
<!-- 无跳转链接 -->
<SidebarMenuButton
v-else
:tooltip="item.title"
>
<!-- 图标名 -->
<Icon
v-if="item.icon && typeof item.icon === 'string'"
:name="item.icon"
size="16px"
/>
<!-- 图标组件 -->
<component
:is="item.icon"
v-else
/>
<span>{{ item.title }}</span>
<ChevronRight
v-if="item.items"
class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
/>
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent v-if="item.items">
<SidebarMenuSub>
<SidebarMenuSubItem
v-for="subItem in item.items"
:key="subItem.title"
>
<NuxtLink
v-slot="{ isActive, href, navigate }"
:to="subItem.url"
custom
>
<SidebarMenuSubButton
as="a"
as-child
:is-active="isActive"
:href
@click="navigate"
>
<span>{{ subItem.title }}</span>
</SidebarMenuSubButton>
</NuxtLink>
</SidebarMenuSubItem>
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
</SidebarMenu>
</SidebarGroup>
</template>