NavigationMenu
用法
使用 NavigationMenu 组件水平或垂直显示链接列表。
<script setup lang="ts">
const items = ref([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
])
</script>
<template>
<UNavigationMenu :items="items" />
</template>
项
将 items
属性用作具有以下属性的对象数组
label?: string
icon?: string
avatar?: AvatarProps
badge?: string | number | BadgeProps
tooltip?: TooltipProps
trailingIcon?: string
type?: 'label' | 'trigger' | 'link'
defaultOpen?: boolean
open?: boolean
value?: string
disabled?: boolean
slot?: string
onSelect?: (e: Event) => void
children?: NavigationMenuChildItem[]
class?: any
ui?: { linkLeadingAvatarSize?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLabel?: ClassNameValue, linkLabelExternalIcon?: ClassNameValue, linkTrailing?: ClassNameValue, linkTrailingBadgeSize?: ClassNameValue, linkTrailingBadge?: ClassNameValue, linkTrailingIcon?: ClassNameValue, label?: ClassNameValue, link?: ClassNameValue, content?: ClassNameValue, childList?: ClassNameValue, childLabel?: ClassNameValue, childItem?: ClassNameValue, childLink?: ClassNameValue, childLinkIcon?: ClassNameValue, childLinkWrapper?: ClassNameValue, childLinkLabel?: ClassNameValue, childLinkLabelExternalIcon?: ClassNameValue, childLinkDescription?: ClassNameValue }
您可以传递 Link 组件的任何属性,例如 to
、target
等。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[]>([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
])
</script>
<template>
<UNavigationMenu :items="items" class="w-full justify-center" />
</template>
items
prop 来显示项目组。children
数组对象,其中包含以下属性,以创建子菜单label: string
description?: string
icon?: string
onSelect?: (e: Event) => void
class?: any
Orientation
使用 orientation
prop 来更改 NavigationMenu 的方向。
vertical
时,会使用 Accordion 组件来显示每个组。您可以使用 open
和 defaultOpen
属性来控制每个项目的打开状态,并使用 collapsible
和 type
props 来更改行为。<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Links',
type: 'label'
},
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
defaultOpen: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
]
])
</script>
<template>
<UNavigationMenu orientation="vertical" :items="items" class="data-[orientation=vertical]:w-48" />
</template>
horizontal
时,组之间会有间距;当 orientation 为 vertical
时,组之间会有分隔。折叠
在 vertical
orientation 中,使用 collapsed
prop 来折叠 NavigationMenu,这在侧边栏中会很有用。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Links',
type: 'label'
},
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
]
])
</script>
<template>
<UNavigationMenu collapsed orientation="vertical" :items="items" />
</template>
高亮显示
使用 highlight
prop 为活动项目显示高亮边框。
使用 highlight-color
prop 来更改边框颜色。它默认使用 color
prop 的颜色。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description:
'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
defaultOpen: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
]
])
</script>
<template>
<UNavigationMenu
highlight
highlight-color="primary"
orientation="horizontal"
:items="items"
class="data-[orientation=horizontal]:border-b border-default data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-48"
/>
</template>
border-b
类应用于 horizontal
orientation 中显示边框,但这并非默认行为,以便为您提供一个干净的起点。vertical
orientation 中,highlight
prop 只会高亮活动子项的边框。颜色
使用 color
prop 来更改 NavigationMenu 的颜色。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started'
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables'
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
}
]
])
</script>
<template>
<UNavigationMenu color="neutral" :items="items" class="w-full" />
</template>
变体
使用 variant
prop 来更改 NavigationMenu 的变体。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started'
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables'
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank'
}
]
])
</script>
<template>
<UNavigationMenu color="neutral" variant="link" :items="items" class="w-full" />
</template>
highlight
prop 会更改 pill
变体活动项的样式。可以尝试一下看看区别。尾部图标
使用 trailing-icon
prop 来自定义每个项目的尾部 Icon。默认为 i-lucide-chevron-down
。此图标仅在项目有子项时显示。
trailingIcon
属性为特定项目设置图标。<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[]>([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
])
</script>
<template>
<UNavigationMenu trailing-icon="i-lucide-arrow-down" :items="items" class="w-full justify-center" />
</template>
箭头
使用 arrow
prop 在 NavigationMenu 内容中带有子项的项目旁边显示一个箭头。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[]>([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
])
</script>
<template>
<UNavigationMenu arrow :items="items" class="w-full justify-center" />
</template>
内容方向
使用 content-orientation
prop 来更改内容的显示方向。
orientation
为 horizontal
时生效。<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[]>([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
}
]
}
])
</script>
<template>
<UNavigationMenu arrow content-orientation="vertical" :items="items" class="w-full justify-center" />
</template>
卸载
使用 unmount-on-hide
prop 来控制内容卸载行为。默认为 true
。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[]>([
{
label: 'Guide',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
to: '/docs/composables',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
])
</script>
<template>
<UNavigationMenu :unmount-on-hide="false" :items="items" class="w-full justify-center" />
</template>
示例
项目带有 tooltip
当 orientation 为 vertical
且菜单处于 collapsed
状态时,您可以将 tooltip
prop 设置为 true
,以在项目周围显示 Tooltip(显示项目标签),但您也可以在每个项目上使用 tooltip
属性来覆盖默认 tooltip。
您可以全局或在每个项目上通过 Tooltip 组件传递任何属性。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Links',
type: 'label'
},
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank',
tooltip: {
text: 'Open on GitHub',
kbds: [
'3.8k'
]
}
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
]
])
</script>
<template>
<UNavigationMenu tooltip collapsed orientation="vertical" :items="items" />
</template>
项目带有 popover
当 orientation 为 vertical
且菜单处于 collapsed
状态时,您可以将 popover
prop 设置为 true
,以在项目周围显示 Popover(显示项目子项),但您也可以在每个项目上使用 popover
属性来覆盖默认 popover。
您可以全局或在每个项目上通过 Popover 组件传递任何属性。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = ref<NavigationMenuItem[][]>([
[
{
label: 'Links',
type: 'label'
},
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
popover: {
mode: 'click'
},
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.',
to: '/docs/composables/define-shortcuts'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.',
to: '/docs/composables/use-overlay'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.',
to: '/docs/composables/use-toast'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
to: '/docs/components',
active: true,
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.',
to: '/docs/components/link'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.',
to: '/docs/components/modal'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.',
to: '/docs/components/navigation-menu'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.',
to: '/docs/components/pagination'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.',
to: '/docs/components/popover'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.',
to: '/docs/components/progress'
}
]
}
],
[
{
label: 'GitHub',
icon: 'i-simple-icons-github',
badge: '3.8k',
to: 'https://github.com/nuxt/ui',
target: '_blank',
tooltip: {
text: 'Open on GitHub',
kbds: [
'3.8k'
]
}
},
{
label: 'Help',
icon: 'i-lucide-circle-help',
disabled: true
}
]
])
</script>
<template>
<UNavigationMenu popover collapsed orientation="vertical" :items="items" />
</template>
控制活动项目
您可以通过使用 default-value
属性或 v-model
指令与项目索引来控制活动项目。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items: NavigationMenuItem[] = [
{
label: 'Guide',
icon: 'i-lucide-book-open',
children: [
{
label: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
icon: 'i-lucide-house'
},
{
label: 'Installation',
description: 'Learn how to install and configure Nuxt UI in your application.',
icon: 'i-lucide-cloud-download'
},
{
label: 'Icons',
icon: 'i-lucide-smile',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
icon: 'i-lucide-cog',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Composables',
icon: 'i-lucide-database',
children: [
{
label: 'defineShortcuts',
icon: 'i-lucide-file-text',
description: 'Define shortcuts for your application.'
},
{
label: 'useOverlay',
icon: 'i-lucide-file-text',
description: 'Display a modal/slideover within your application.'
},
{
label: 'useToast',
icon: 'i-lucide-file-text',
description: 'Display a toast within your application.'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
children: [
{
label: 'Link',
icon: 'i-lucide-file-text',
description: 'Use NuxtLink with superpowers.'
},
{
label: 'Modal',
icon: 'i-lucide-file-text',
description: 'Display a modal within your application.'
},
{
label: 'NavigationMenu',
icon: 'i-lucide-file-text',
description: 'Display a list of links.'
},
{
label: 'Pagination',
icon: 'i-lucide-file-text',
description: 'Display a list of pages.'
},
{
label: 'Popover',
icon: 'i-lucide-file-text',
description: 'Display a non-modal dialog that floats around a trigger element.'
},
{
label: 'Progress',
icon: 'i-lucide-file-text',
description: 'Show a horizontal bar to indicate task progression.'
}
]
}
]
const active = ref()
defineShortcuts({
1: () => {
active.value = '0'
},
2: () => {
active.value = '1'
},
3: () => {
active.value = '2'
}
})
</script>
<template>
<UNavigationMenu v-model="active" :items="items" class="w-full justify-center" />
</template>
defineShortcuts
,您可以通过按 1、2 或 3 来切换活动项目。带自定义插槽
使用 slot
属性自定义特定项。
您将可以使用以下插槽
#{{ item.slot }}
#{{ item.slot }}-leading
#{{ item.slot }}-label
#{{ item.slot }}-trailing
#{{ item.slot }}-content
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = [
{
label: 'Guide',
icon: 'i-lucide-book-open'
},
{
label: 'Composables',
icon: 'i-lucide-database'
},
{
label: 'Components',
icon: 'i-lucide-box',
slot: 'components' as const
}
] satisfies NavigationMenuItem[]
</script>
<template>
<UNavigationMenu :items="items" class="w-full justify-center">
<template #components-trailing>
<UBadge label="44" variant="subtle" size="sm" />
</template>
</UNavigationMenu>
</template>
使用 `content` 插槽
使用 #item-content
slot 或 slot
属性(#{{ item.slot }}-content
)来定制特定项目的 content
。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'
const items = [
{
label: 'Docs',
icon: 'i-lucide-book-open',
slot: 'docs' as const,
children: [
{
label: 'Icons',
description: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
description: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Theme',
description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
},
{
label: 'Components',
icon: 'i-lucide-box',
slot: 'components' as const,
children: [
{
label: 'Link',
description: 'Use NuxtLink with superpowers.'
},
{
label: 'Modal',
description: 'Display a modal within your application.'
},
{
label: 'NavigationMenu',
description: 'Display a list of links.'
},
{
label: 'Pagination',
description: 'Display a list of pages.'
},
{
label: 'Popover',
description: 'Display a non-modal dialog that floats around a trigger element.'
},
{
label: 'Progress',
description: 'Show a horizontal bar to indicate task progression.'
}
]
},
{
label: 'GitHub',
icon: 'i-simple-icons-github'
}
] satisfies NavigationMenuItem[]
</script>
<template>
<UNavigationMenu
:items="items"
:ui="{
viewport: 'sm:w-(--reka-navigation-menu-viewport-width)',
content: 'sm:w-auto',
childList: 'sm:w-96',
childLinkDescription: 'text-balance line-clamp-2'
}"
class="w-full justify-center"
>
<template #docs-content="{ item }">
<ul class="grid gap-2 p-4 lg:w-[500px] lg:grid-cols-[minmax(0,.75fr)_minmax(0,1fr)]">
<li class="row-span-3">
<Placeholder class="size-full min-h-48" />
</li>
<li v-for="child in item.children" :key="child.label">
<ULink class="text-sm text-left rounded-md p-3 transition-colors hover:bg-elevated/50">
<p class="font-medium text-highlighted">
{{ child.label }}
</p>
<p class="text-muted line-clamp-2">
{{ child.description }}
</p>
</ULink>
</li>
</ul>
</template>
</UNavigationMenu>
</template>
viewport
上添加了 sm:w-(--reka-navigation-menu-viewport-width)
类以获得动态宽度。这需要为内容的第一个子项设置宽度。API
属性
属性 | 默认值 | 类型 |
---|---|---|
as |
|
此组件应渲染为的元素或组件。 |
trailingIcon |
|
用于打开菜单的图标。 |
externalIcon |
|
当项是外部链接时显示的图标。设置为 |
items |
| |
color |
|
|
variant |
|
|
orientation |
|
菜单的方向。 |
collapsed |
|
折叠导航菜单,只显示图标。仅在 |
tooltip |
|
在菜单折叠时,显示项目的 tooltip,内容为项目标签。这优先于全局
|
popover |
|
在菜单折叠时,显示项目的 popover,内容为项目子列表。 |
高亮 |
显示一条线在活动项目旁边。 | |
highlightColor |
|
|
内容 |
菜单的内容。
| |
contentOrientation |
|
内容的显示方向。仅在 |
arrow |
|
在菜单旁边显示一个箭头。 |
labelKey |
|
用于从项中获取标签的键。 |
modelValue |
菜单项的受控值,用于激活。可以用作 | |
defaultValue |
菜单项的初始渲染值。 当您不需要控制状态值时使用。 | |
delayDuration |
|
从指针进入触发器到 tooltip 打开的时间。 |
disableClickTrigger |
|
如果为 |
disableHoverTrigger |
|
如果为 |
skipDelayDuration |
|
用户在不产生延迟的情况下,能够进入另一个触发器的最短时间。 |
disablePointerLeaveClose |
|
如果为 |
unmountOnHide |
|
当为 `true` 时,元素在关闭状态下将被卸载。 |
disabled |
|
当为 `true` 时,防止用户与折叠面板及其所有项目交互。 |
type |
|
确定一次可以选择“单个”还是“多个”项目。 此 prop 将覆盖从 |
collapsible |
|
当类型为“single”时,允许在点击已打开的项目触发器时关闭内容。当类型为“multiple”时,此属性无效。 |
ui |
|
插槽
插槽 | 类型 |
---|---|
item |
|
item-leading |
|
item-label |
|
item-trailing |
|
item-content |
|
list-leading |
|
list-trailing |
|
事件
事件 | 类型 |
---|---|
update:modelValue |
|
主题
export default defineAppConfig({
ui: {
navigationMenu: {
slots: {
root: 'relative flex gap-1.5 [&>div]:min-w-0',
list: 'isolate min-w-0',
label: 'w-full flex items-center gap-1.5 font-semibold text-xs/5 text-highlighted px-2.5 py-1.5',
item: 'min-w-0',
link: 'group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2',
linkLeadingIcon: 'shrink-0 size-5',
linkLeadingAvatar: 'shrink-0',
linkLeadingAvatarSize: '2xs',
linkTrailing: 'group ms-auto inline-flex gap-1.5 items-center',
linkTrailingBadge: 'shrink-0',
linkTrailingBadgeSize: 'sm',
linkTrailingIcon: 'size-5 transform shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
linkLabel: 'truncate',
linkLabelExternalIcon: 'inline-block size-3 align-top text-dimmed',
childList: 'isolate',
childLabel: 'text-xs text-highlighted',
childItem: '',
childLink: 'group relative size-full flex items-start text-start text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2',
childLinkWrapper: 'min-w-0',
childLinkIcon: 'size-5 shrink-0',
childLinkLabel: 'truncate',
childLinkLabelExternalIcon: 'inline-block size-3 align-top text-dimmed',
childLinkDescription: 'text-muted',
separator: 'px-2 h-px bg-border',
viewportWrapper: 'absolute top-full left-0 flex w-full',
viewport: 'relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]',
content: '',
indicator: 'absolute data-[state=visible]:animate-[fade-in_100ms_ease-out] data-[state=hidden]:animate-[fade-out_100ms_ease-in] data-[state=hidden]:opacity-0 bottom-0 z-[2] w-(--reka-navigation-menu-indicator-size) translate-x-(--reka-navigation-menu-indicator-position) flex h-2.5 items-end justify-center overflow-hidden transition-[translate,width] duration-200',
arrow: 'relative top-[50%] size-2.5 rotate-45 border border-default bg-default z-[1] rounded-xs'
},
variants: {
color: {
primary: {
link: 'focus-visible:before:ring-primary',
childLink: 'focus-visible:before:ring-primary'
},
secondary: {
link: 'focus-visible:before:ring-secondary',
childLink: 'focus-visible:before:ring-secondary'
},
success: {
link: 'focus-visible:before:ring-success',
childLink: 'focus-visible:before:ring-success'
},
info: {
link: 'focus-visible:before:ring-info',
childLink: 'focus-visible:before:ring-info'
},
warning: {
link: 'focus-visible:before:ring-warning',
childLink: 'focus-visible:before:ring-warning'
},
error: {
link: 'focus-visible:before:ring-error',
childLink: 'focus-visible:before:ring-error'
},
neutral: {
link: 'focus-visible:before:ring-inverted',
childLink: 'focus-visible:before:ring-inverted'
}
},
highlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
variant: {
pill: '',
link: ''
},
orientation: {
horizontal: {
root: 'items-center justify-between',
list: 'flex items-center',
item: 'py-2',
link: 'px-2.5 py-1.5 before:inset-x-px before:inset-y-0',
childList: 'grid p-2',
childLink: 'px-3 py-2 gap-2 before:inset-x-px before:inset-y-0',
childLinkLabel: 'font-medium',
content: 'absolute top-0 left-0 w-full max-h-[70vh] overflow-y-auto'
},
vertical: {
root: 'flex-col',
link: 'flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0',
childLabel: 'px-1.5 py-0.5',
childLink: 'p-1.5 gap-1.5 before:inset-y-px before:inset-x-0'
}
},
contentOrientation: {
horizontal: {
viewportWrapper: 'justify-center',
content: 'data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]'
},
vertical: {
viewport: 'sm:w-(--reka-navigation-menu-viewport-width) left-(--reka-navigation-menu-viewport-left)'
}
},
active: {
true: {
childLink: 'before:bg-elevated text-highlighted',
childLinkIcon: 'text-default'
},
false: {
link: 'text-muted',
linkLeadingIcon: 'text-dimmed',
childLink: [
'hover:before:bg-elevated/50 text-default hover:text-highlighted',
'transition-colors before:transition-colors'
],
childLinkIcon: [
'text-dimmed group-hover:text-default',
'transition-colors'
]
}
},
disabled: {
true: {
link: 'cursor-not-allowed opacity-75'
}
},
highlight: {
true: ''
},
level: {
true: ''
},
collapsed: {
true: ''
}
},
compoundVariants: [
{
orientation: 'horizontal',
contentOrientation: 'horizontal',
class: {
childList: 'grid-cols-2 gap-2'
}
},
{
orientation: 'horizontal',
contentOrientation: 'vertical',
class: {
childList: 'gap-1',
content: 'w-60'
}
},
{
orientation: 'vertical',
collapsed: false,
class: {
childList: 'ms-5 border-s border-default',
childItem: 'ps-1.5 -ms-px',
content: 'data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden'
}
},
{
orientation: 'vertical',
collapsed: true,
class: {
link: 'px-1.5',
content: 'shadow-sm rounded-sm min-h-6 p-1'
}
},
{
orientation: 'horizontal',
highlight: true,
class: {
link: [
'after:absolute after:-bottom-2 after:inset-x-2.5 after:block after:h-px after:rounded-full',
'after:transition-colors'
]
}
},
{
orientation: 'vertical',
highlight: true,
level: true,
class: {
link: [
'after:absolute after:-start-1.5 after:inset-y-0.5 after:block after:w-px after:rounded-full',
'after:transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'pill',
class: {
link: [
'hover:text-highlighted hover:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
linkLeadingIcon: [
'group-hover:text-default',
'transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'pill',
orientation: 'horizontal',
class: {
link: 'data-[state=open]:text-highlighted',
linkLeadingIcon: 'group-data-[state=open]:text-default'
}
},
{
disabled: false,
variant: 'pill',
highlight: true,
orientation: 'horizontal',
class: {
link: 'data-[state=open]:before:bg-elevated/50'
}
},
{
disabled: false,
variant: 'pill',
highlight: false,
active: false,
orientation: 'horizontal',
class: {
link: 'data-[state=open]:before:bg-elevated/50'
}
},
{
color: 'primary',
variant: 'pill',
active: true,
class: {
link: 'text-primary',
linkLeadingIcon: 'text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'neutral',
variant: 'pill',
active: true,
class: {
link: 'text-highlighted',
linkLeadingIcon: 'text-highlighted group-data-[state=open]:text-highlighted'
}
},
{
variant: 'pill',
active: true,
highlight: false,
class: {
link: 'before:bg-elevated'
}
},
{
variant: 'pill',
active: true,
highlight: true,
disabled: false,
class: {
link: [
'hover:before:bg-elevated/50',
'before:transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'link',
class: {
link: [
'hover:text-highlighted',
'transition-colors'
],
linkLeadingIcon: [
'group-hover:text-default',
'transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'link',
orientation: 'horizontal',
class: {
link: 'data-[state=open]:text-highlighted',
linkLeadingIcon: 'group-data-[state=open]:text-default'
}
},
{
color: 'primary',
variant: 'link',
active: true,
class: {
link: 'text-primary',
linkLeadingIcon: 'text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'neutral',
variant: 'link',
active: true,
class: {
link: 'text-highlighted',
linkLeadingIcon: 'text-highlighted group-data-[state=open]:text-highlighted'
}
},
{
highlightColor: 'primary',
highlight: true,
level: true,
active: true,
class: {
link: 'after:bg-primary'
}
},
{
highlightColor: 'neutral',
highlight: true,
level: true,
active: true,
class: {
link: 'after:bg-inverted'
}
}
],
defaultVariants: {
color: 'primary',
highlightColor: 'primary',
variant: 'pill'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
navigationMenu: {
slots: {
root: 'relative flex gap-1.5 [&>div]:min-w-0',
list: 'isolate min-w-0',
label: 'w-full flex items-center gap-1.5 font-semibold text-xs/5 text-highlighted px-2.5 py-1.5',
item: 'min-w-0',
link: 'group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2',
linkLeadingIcon: 'shrink-0 size-5',
linkLeadingAvatar: 'shrink-0',
linkLeadingAvatarSize: '2xs',
linkTrailing: 'group ms-auto inline-flex gap-1.5 items-center',
linkTrailingBadge: 'shrink-0',
linkTrailingBadgeSize: 'sm',
linkTrailingIcon: 'size-5 transform shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
linkLabel: 'truncate',
linkLabelExternalIcon: 'inline-block size-3 align-top text-dimmed',
childList: 'isolate',
childLabel: 'text-xs text-highlighted',
childItem: '',
childLink: 'group relative size-full flex items-start text-start text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2',
childLinkWrapper: 'min-w-0',
childLinkIcon: 'size-5 shrink-0',
childLinkLabel: 'truncate',
childLinkLabelExternalIcon: 'inline-block size-3 align-top text-dimmed',
childLinkDescription: 'text-muted',
separator: 'px-2 h-px bg-border',
viewportWrapper: 'absolute top-full left-0 flex w-full',
viewport: 'relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]',
content: '',
indicator: 'absolute data-[state=visible]:animate-[fade-in_100ms_ease-out] data-[state=hidden]:animate-[fade-out_100ms_ease-in] data-[state=hidden]:opacity-0 bottom-0 z-[2] w-(--reka-navigation-menu-indicator-size) translate-x-(--reka-navigation-menu-indicator-position) flex h-2.5 items-end justify-center overflow-hidden transition-[translate,width] duration-200',
arrow: 'relative top-[50%] size-2.5 rotate-45 border border-default bg-default z-[1] rounded-xs'
},
variants: {
color: {
primary: {
link: 'focus-visible:before:ring-primary',
childLink: 'focus-visible:before:ring-primary'
},
secondary: {
link: 'focus-visible:before:ring-secondary',
childLink: 'focus-visible:before:ring-secondary'
},
success: {
link: 'focus-visible:before:ring-success',
childLink: 'focus-visible:before:ring-success'
},
info: {
link: 'focus-visible:before:ring-info',
childLink: 'focus-visible:before:ring-info'
},
warning: {
link: 'focus-visible:before:ring-warning',
childLink: 'focus-visible:before:ring-warning'
},
error: {
link: 'focus-visible:before:ring-error',
childLink: 'focus-visible:before:ring-error'
},
neutral: {
link: 'focus-visible:before:ring-inverted',
childLink: 'focus-visible:before:ring-inverted'
}
},
highlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
variant: {
pill: '',
link: ''
},
orientation: {
horizontal: {
root: 'items-center justify-between',
list: 'flex items-center',
item: 'py-2',
link: 'px-2.5 py-1.5 before:inset-x-px before:inset-y-0',
childList: 'grid p-2',
childLink: 'px-3 py-2 gap-2 before:inset-x-px before:inset-y-0',
childLinkLabel: 'font-medium',
content: 'absolute top-0 left-0 w-full max-h-[70vh] overflow-y-auto'
},
vertical: {
root: 'flex-col',
link: 'flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0',
childLabel: 'px-1.5 py-0.5',
childLink: 'p-1.5 gap-1.5 before:inset-y-px before:inset-x-0'
}
},
contentOrientation: {
horizontal: {
viewportWrapper: 'justify-center',
content: 'data-[motion=from-start]:animate-[enter-from-left_200ms_ease] data-[motion=from-end]:animate-[enter-from-right_200ms_ease] data-[motion=to-start]:animate-[exit-to-left_200ms_ease] data-[motion=to-end]:animate-[exit-to-right_200ms_ease]'
},
vertical: {
viewport: 'sm:w-(--reka-navigation-menu-viewport-width) left-(--reka-navigation-menu-viewport-left)'
}
},
active: {
true: {
childLink: 'before:bg-elevated text-highlighted',
childLinkIcon: 'text-default'
},
false: {
link: 'text-muted',
linkLeadingIcon: 'text-dimmed',
childLink: [
'hover:before:bg-elevated/50 text-default hover:text-highlighted',
'transition-colors before:transition-colors'
],
childLinkIcon: [
'text-dimmed group-hover:text-default',
'transition-colors'
]
}
},
disabled: {
true: {
link: 'cursor-not-allowed opacity-75'
}
},
highlight: {
true: ''
},
level: {
true: ''
},
collapsed: {
true: ''
}
},
compoundVariants: [
{
orientation: 'horizontal',
contentOrientation: 'horizontal',
class: {
childList: 'grid-cols-2 gap-2'
}
},
{
orientation: 'horizontal',
contentOrientation: 'vertical',
class: {
childList: 'gap-1',
content: 'w-60'
}
},
{
orientation: 'vertical',
collapsed: false,
class: {
childList: 'ms-5 border-s border-default',
childItem: 'ps-1.5 -ms-px',
content: 'data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden'
}
},
{
orientation: 'vertical',
collapsed: true,
class: {
link: 'px-1.5',
content: 'shadow-sm rounded-sm min-h-6 p-1'
}
},
{
orientation: 'horizontal',
highlight: true,
class: {
link: [
'after:absolute after:-bottom-2 after:inset-x-2.5 after:block after:h-px after:rounded-full',
'after:transition-colors'
]
}
},
{
orientation: 'vertical',
highlight: true,
level: true,
class: {
link: [
'after:absolute after:-start-1.5 after:inset-y-0.5 after:block after:w-px after:rounded-full',
'after:transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'pill',
class: {
link: [
'hover:text-highlighted hover:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
linkLeadingIcon: [
'group-hover:text-default',
'transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'pill',
orientation: 'horizontal',
class: {
link: 'data-[state=open]:text-highlighted',
linkLeadingIcon: 'group-data-[state=open]:text-default'
}
},
{
disabled: false,
variant: 'pill',
highlight: true,
orientation: 'horizontal',
class: {
link: 'data-[state=open]:before:bg-elevated/50'
}
},
{
disabled: false,
variant: 'pill',
highlight: false,
active: false,
orientation: 'horizontal',
class: {
link: 'data-[state=open]:before:bg-elevated/50'
}
},
{
color: 'primary',
variant: 'pill',
active: true,
class: {
link: 'text-primary',
linkLeadingIcon: 'text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'neutral',
variant: 'pill',
active: true,
class: {
link: 'text-highlighted',
linkLeadingIcon: 'text-highlighted group-data-[state=open]:text-highlighted'
}
},
{
variant: 'pill',
active: true,
highlight: false,
class: {
link: 'before:bg-elevated'
}
},
{
variant: 'pill',
active: true,
highlight: true,
disabled: false,
class: {
link: [
'hover:before:bg-elevated/50',
'before:transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'link',
class: {
link: [
'hover:text-highlighted',
'transition-colors'
],
linkLeadingIcon: [
'group-hover:text-default',
'transition-colors'
]
}
},
{
disabled: false,
active: false,
variant: 'link',
orientation: 'horizontal',
class: {
link: 'data-[state=open]:text-highlighted',
linkLeadingIcon: 'group-data-[state=open]:text-default'
}
},
{
color: 'primary',
variant: 'link',
active: true,
class: {
link: 'text-primary',
linkLeadingIcon: 'text-primary group-data-[state=open]:text-primary'
}
},
{
color: 'neutral',
variant: 'link',
active: true,
class: {
link: 'text-highlighted',
linkLeadingIcon: 'text-highlighted group-data-[state=open]:text-highlighted'
}
},
{
highlightColor: 'primary',
highlight: true,
level: true,
active: true,
class: {
link: 'after:bg-primary'
}
},
{
highlightColor: 'neutral',
highlight: true,
level: true,
active: true,
class: {
link: 'after:bg-inverted'
}
}
],
defaultVariants: {
color: 'primary',
highlightColor: 'primary',
variant: 'pill'
}
}
}
})
]
})
更新日志
f2420
— fix: display trailing slot when badge not undefined
5cb65
— 特性:导入 @nuxt/ui-pro
组件
b2289
— fix: display badge when not undefined
836f7
— fix: proxy fallthrough attributes
9cf9f
— feat: add trigger
type in items
f2682
— feat: add tooltip
and popover
props
44f53
— fix: only display tooltip
when collapsed
1e2a1
— feat: handle vertical
orientation with Accordion instead of Collapsible
3c78e
— fix!: revert new collapsible
field
0905b
— chore: 将 item.class
移回链接上
2be60
— feat: add collapsible
field in items
46c29
— feat: handle tooltip
in items
e6e51
— fix:class
应该优先于 ui
属性
af1bf
— chore: remove slots types in createReusableTemplate
5dec0
— feat: 处理 content
属性中的事件
ef861
— chore: 在 script 标签中添加 eol 以修复语法高亮