IntelliClass_FE/components/app/NavMain.vue
2025-04-03 22:57:36 +08:00

114 lines
3.5 KiB
Vue

<script setup lang="ts">
import { ChevronRight, type LucideIcon } from "lucide-vue-next";
import type { RouteLocationRaw } from "vue-router";
defineProps<{
nav: {
label?: string;
items: {
title: string;
url?: RouteLocationRaw | string;
icon: LucideIcon | string;
isActive?: boolean;
items?: {
title: string;
url: string;
}[];
}[];
}[];
}>();
</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-6"
:to="item.url"
custom
>
<SidebarMenuButton
as="a"
class="flex justify-start text-base pl-8"
:tooltip="item.title"
:is-active="isActive"
:href
@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"
/>
</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>