跳到内容

导航菜单

用于网站导航的一组链接。
vue
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { ref } from 'vue'
import {
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
import NavigationMenuListItem from './NavigationMenuListItem.vue'

const currentTrigger = ref('')
</script>

<template>
  <NavigationMenuRoot
    v-model="currentTrigger"
    class="relative z-[1] flex w-full justify-center"
  >
    <NavigationMenuList class="center shadow-blackA7 m-0 flex list-none rounded-[6px] bg-white p-1 shadow-[0_2px_10px]">
      <NavigationMenuItem>
        <NavigationMenuTrigger
          class="text-grass11 hover:bg-green3 focus:shadow-green7 group flex select-none items-center justify-between gap-[2px] rounded-[4px] px-3 py-2 text-[15px] font-medium leading-none outline-none focus:shadow-[0_0_0_2px]"
        >
          Learn
          <Icon
            icon="radix-icons:caret-down"
            class="text-green10 relative top-[1px] transition-transform duration-[250ms] ease-in group-data-[state=open]:-rotate-180"
          />
        </NavigationMenuTrigger>
        <NavigationMenuContent
          class="data-[motion=from-start]:animate-enterFromLeft data-[motion=from-end]:animate-enterFromRight data-[motion=to-start]:animate-exitToLeft data-[motion=to-end]:animate-exitToRight absolute top-0 left-0 w-full sm:w-auto"
        >
          <ul class="one m-0 grid list-none gap-x-[10px] p-[22px] sm:w-[500px] sm:grid-cols-[0.75fr_1fr]">
            <li class="row-span-3 grid">
              <NavigationMenuLink as-child>
                <a
                  class="focus:shadow-green7 from-green9 to-teal9 flex h-full w-full select-none flex-col justify-end rounded-[6px] bg-gradient-to-b p-[25px] no-underline outline-none focus:shadow-[0_0_0_2px]"
                  href="/"
                >
                  <img
                    class="w-16"
                    src="https://vue.radix-ui.com.cn/logo.svg"
                  >
                  <div class="mt-4 mb-[7px] text-[18px] font-medium leading-[1.2] text-white">Radix Primitives</div>
                  <p class="text-mauve4 text-[14px] leading-[1.3]">Unstyled, accessible components for Vue.</p>
                </a>
              </NavigationMenuLink>
            </li>

            <NavigationMenuListItem
              href="https://stitches.dev/"
              title="Stitches"
            >
              CSS-in-JS with best-in-class developer experience.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              href="/colors"
              title="Colors"
            >
              Beautiful, thought-out palettes with auto dark mode.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              href="https://icons.radix-ui.com/"
              title="Icons"
            >
              A crisp set of 15x15 icons, balanced and consistent.
            </NavigationMenuListItem>
          </ul>
        </NavigationMenuContent>
      </NavigationMenuItem>

      <NavigationMenuItem>
        <NavigationMenuTrigger
          class="text-grass11 hover:bg-green3 focus:shadow-green7 group flex select-none items-center justify-between gap-[2px] rounded-[4px] px-3 py-2 text-[15px] font-medium leading-none outline-none focus:shadow-[0_0_0_2px]"
        >
          Overview
          <Icon
            icon="radix-icons:caret-down"
            class="text-green10 relative top-[1px] transition-transform duration-[250ms] ease-in group-data-[state=open]:-rotate-180"
          />
        </NavigationMenuTrigger>
        <NavigationMenuContent class="data-[motion=from-start]:animate-enterFromLeft data-[motion=from-end]:animate-enterFromRight data-[motion=to-start]:animate-exitToLeft data-[motion=to-end]:animate-exitToRight absolute top-0 left-0 w-full sm:w-auto">
          <ul class="m-0 grid list-none gap-x-[10px] p-[22px] sm:w-[600px] sm:grid-flow-col sm:grid-rows-3">
            <NavigationMenuListItem
              title="Introduction"
              href="/docs/primitives/overview/introduction"
            >
              Build high-quality, accessible design systems and web apps.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              title="Getting started"
              href="/docs/primitives/overview/getting-started"
            >
              A quick tutorial to get you up and running with Radix Primitives.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              title="Styling"
              href="/docs/primitives/guides/styling"
            >
              Unstyled and compatible with any styling solution.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              title="Animation"
              href="/docs/primitives/guides/animation"
            >
              Use CSS keyframes or any animation library of your choice.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              title="Accessibility"
              href="/docs/primitives/overview/accessibility"
            >
              Tested in a range of browsers and assistive technologies.
            </NavigationMenuListItem>
            <NavigationMenuListItem
              title="Releases"
              href="/docs/primitives/overview/releases"
            >
              Radix Primitives releases and their changelogs.
            </NavigationMenuListItem>
          </ul>
        </NavigationMenuContent>
      </NavigationMenuItem>

      <NavigationMenuItem>
        <NavigationMenuLink
          class="text-grass11 hover:bg-green3 focus:shadow-green7 block select-none rounded-[4px] px-3 py-2 text-[15px] font-medium leading-none no-underline outline-none focus:shadow-[0_0_0_2px]"
          href="https://github.com/radix-vue"
        >
          Github
        </NavigationMenuLink>
      </NavigationMenuItem>

      <NavigationMenuIndicator
        class="data-[state=hidden]:opacity-0 duration-200 data-[state=visible]:animate-fadeIn data-[state=hidden]:animate-fadeOut top-full z-[1] flex h-[10px] items-end justify-center overflow-hidden transition-[all,transform_250ms_ease]"
      >
        <div class="relative top-[70%] h-[10px] w-[10px] rotate-[45deg] rounded-tl-[2px] bg-white" />
      </NavigationMenuIndicator>
    </NavigationMenuList>

    <div class="perspective-[2000px] absolute top-full left-0 flex w-full justify-center">
      <NavigationMenuViewport
        class="data-[state=open]:animate-scaleIn data-[state=closed]:animate-scaleOut relative mt-[10px] h-[var(--radix-navigation-menu-viewport-height)] w-full origin-[top_center] overflow-hidden rounded-[10px] bg-white transition-[width,_height] duration-300 sm:w-[var(--radix-navigation-menu-viewport-width)]"
      />
    </div>
  </NavigationMenuRoot>
</template>

功能

  • 可以是受控的或不受控的。
  • 灵活的布局结构,带有管理的选项卡焦点。
  • 支持子菜单。
  • 可选的活动项目指示器。
  • 完整的键盘导航。
  • 公开 CSS 变量以进行高级动画。
  • 支持自定义时间。

安装

从命令行安装组件。

sh
$ npm add radix-vue

解剖

导入所有部分并将它们组合在一起。

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuSub,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger />
        <NavigationMenuContent>
          <NavigationMenuLink />
        </NavigationMenuContent>
      </NavigationMenuItem>

      <NavigationMenuItem>
        <NavigationMenuLink />
      </NavigationMenuItem>

      <NavigationMenuItem>
        <NavigationMenuTrigger />
        <NavigationMenuContent>
          <NavigationMenuSub>
            <NavigationMenuList />
            <NavigationMenuViewport />
          </NavigationMenuSub>
        </NavigationMenuContent>
      </NavigationMenuItem>

      <NavigationMenuIndicator />
    </NavigationMenuList>

    <NavigationMenuViewport />
  </NavigationMenuRoot>
</template>

API 参考

包含导航菜单的所有部分。

道具默认值类型
as
'nav'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

defaultValue
string

初始渲染时应处于活动状态的菜单项的值。

当您不需要控制值状态时使用。

delayDuration
200
number

指针进入触发器后,直到工具提示打开之前的持续时间。

dir
'ltr' | 'rtl'

组合框的阅读方向(如果适用)。

如果省略,则从 ConfigProvider 全局继承或假设 LTR(从左到右)阅读模式。

disableClickTrigger
false
boolean

如果 true,则无法通过单击触发器打开菜单

disableHoverTrigger
false
boolean

如果 true,则无法通过将鼠标悬停在触发器上打开菜单

modelValue
string

要激活的菜单项的受控值。 可以用作 v-model

orientation
'horizontal'
'vertical' | 'horizontal'

菜单的方向。

skipDelayDuration
300
number

用户在再次遇到延迟之前可以输入另一个触发器的时间。

发出有效载荷
update:modelValue
[value: string]

值更改时调用的事件处理程序。

插槽(默认)有效载荷
modelValue
string

当前输入值

数据属性价值
[data-orientation]"vertical" | "horizontal"

表示子菜单。 在嵌套时将其用作根部分来创建子菜单。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

defaultValue
string

初始渲染时应处于活动状态的菜单项的值。

当您不需要控制值状态时使用。

modelValue
string

要激活的子菜单项的受控值。 可以用作 v-model

orientation
'horizontal'
'vertical' | 'horizontal'

菜单的方向。

发出有效载荷
update:modelValue
[value: string]

值更改时调用的事件处理程序。

插槽(默认)有效载荷
modelValue
string

当前输入值

数据属性价值
[data-orientation]"vertical" | "horizontal"

列表

包含顶级菜单项。

道具默认值类型
as
'ul'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

数据属性价值
[data-orientation]"vertical" | "horizontal"

项目

一个顶级菜单项,包含链接或触发器与内容组合。

道具默认值类型
as
'li'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

value
string

一个唯一的值,在导航菜单受控时将项目与活动值相关联。

此道具在不受控时会自动管理。

触发器

用于切换内容的按钮。

道具默认值类型
as
'button'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

disabled
boolean

true 时,阻止用户与项目进行交互

数据属性价值
[data-state]"open" | "closed"
[data-disabled]禁用时出现

内容

包含与每个触发器相关联的内容。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

disableOutsidePointerEvents
boolean

true 时,将禁用 DismissableLayer 外部的元素上的悬停/焦点/单击交互。 用户需要在外部元素上单击两次才能与它们交互:一次关闭 DismissableLayer,另一次触发元素。

forceMount
boolean

用于在需要更多控制时强制安装。 当使用 Vue 动画库控制动画时很有用。

发出有效载荷
escapeKeyDown
[event: KeyboardEvent]

按下 Escape 键时调用的事件处理程序。 可以防止。

focusOutside
[event: FocusOutsideEvent]

焦点移出 DismissableLayer 时调用的事件处理程序。 可以防止。

interactOutside
[event: PointerDownOutsideEvent | FocusOutsideEvent]

DismissableLayer 外部发生交互时调用的事件处理程序。 具体来说,当 pointerdown 事件发生在外部或焦点移出其外部时。 可以防止。

pointerDownOutside
[event: PointerDownOutsideEvent]

DismissableLayer 外部发生 pointerdown 事件时调用的事件处理程序。 可以防止。

数据属性价值
[data-state]"open" | "closed"
[data-motion]"to-start" | "to-end" | "from-start" | "from-end"
[data-orientation]"vertical" | "horizontal"

一个导航链接。

道具默认值类型
active
boolean

用于识别链接作为当前活动页面。

as
'a'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

发出有效载荷
select
[payload: MouseEvent]

用户选择链接(通过鼠标或键盘)时调用的事件处理程序。

在这个处理程序中调用 event.preventDefault 将阻止导航菜单在选择该链接时关闭。

数据属性价值
[data-active]活动时出现

指示器

一个可选的指示器元素,它渲染在列表下方,用于突出显示当前活动的触发器。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

forceMount
boolean

用于在需要更多控制时强制安装。 当使用 Vue 动画库控制动画时很有用。

数据属性价值
[data-state]"visible" | "hidden"
[data-orientation]"vertical" | "horizontal"

视窗

一个可选的视窗元素,用于渲染列表之外的活动内容。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。 可以被 asChild 覆盖

asChild
boolean

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以了解更多详细信息。

forceMount
boolean

用于在需要更多控制时强制安装。 当使用 Vue 动画库控制动画时很有用。

数据属性价值
[data-state]"visible" | "hidden"
[data-orientation]"vertical" | "horizontal"
CSS 变量描述
--radix-navigation-menu-viewport-width
视窗在可见/隐藏时(从活动内容计算)的宽度
--radix-navigation-menu-viewport-height
视窗在可见/隐藏时(从活动内容计算)的高度

示例

垂直

您可以使用 orientation 道具创建一个垂直菜单。

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuSub,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot orientation="vertical">
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item one</NavigationMenuTrigger>
        <NavigationMenuContent>Item one content</NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item two</NavigationMenuTrigger>
        <NavigationMenuContent>Item Two content</NavigationMenuContent>
      </NavigationMenuItem>
    </NavigationMenuList>
  </NavigationMenuRoot>
</template>

灵活布局

当您需要额外控制 Content 的渲染位置时,请使用 Viewport 部分。 当您的设计需要调整的 DOM 结构或您需要灵活性才能实现 高级动画 时,这很有用。 选项卡焦点将自动维护。

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item one</NavigationMenuTrigger>
        <NavigationMenuContent>Item one content</NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item two</NavigationMenuTrigger>
        <NavigationMenuContent>Item two content</NavigationMenuContent>
      </NavigationMenuItem>
    </NavigationMenuList>

    <!-- NavigationMenuContent will be rendered here when active  -->
    <NavigationMenuViewport />
  </NavigationMenuRoot>
</template>

带指示器

您可以使用可选的 Indicator 部分来突出显示当前活动的 Trigger,这在您想要提供动画视觉提示(例如箭头或突出显示)以配合 Viewport 时很有用。

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item one</NavigationMenuTrigger>
        <NavigationMenuContent>Item one content</NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item two</NavigationMenuTrigger>
        <NavigationMenuContent>Item two content</NavigationMenuContent>
      </NavigationMenuItem>

      <NavigationMenuIndicator class="NavigationMenuIndicator" />
    </NavigationMenuList>

    <NavigationMenuViewport />
  </NavigationMenuRoot>
</template>
css
/* styles.css */
.NavigationMenuIndicator {
  background-color: grey;
}
.NavigationMenuIndicator[data-orientation="horizontal"] {
  height: 3px;
  transition: width, transform, 250ms ease;
}

带子菜单

通过嵌套您的 NavigationMenu 并在其 Root 位置使用 Sub 部分来创建一个子菜单。 子菜单的工作方式不同于 Root 导航菜单,类似于 Tabs,其中一项应该始终处于活动状态,因此请务必分配并设置 defaultValue

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuSub,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item one</NavigationMenuTrigger>
        <NavigationMenuContent>Item one content</NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item two</NavigationMenuTrigger>
        <NavigationMenuContent>
          <NavigationMenuSub default-value="sub1">
            <NavigationMenuList>
              <NavigationMenuItem value="sub1">
                <NavigationMenuTrigger>Sub item one</NavigationMenuTrigger>
                <NavigationMenuContent> Sub item one content </NavigationMenuContent>
              </NavigationMenuItem>
              <NavigationMenuItem value="sub2">
                <NavigationMenuTrigger>Sub item two</NavigationMenuTrigger>
                <NavigationMenuContent> Sub item two content </NavigationMenuContent>
              </NavigationMenuItem>
            </NavigationMenuList>
          </NavigationMenuSub>
        </NavigationMenuContent>
      </NavigationMenuItem>
    </NavigationMenuList>
  </NavigationMenuRoot>
</template>

带客户端路由

如果您需要使用路由包提供的RouterLink组件,我们建议您在NavigationMenuLink中添加asChild="true",或设置as="RouterLink"。这将确保可访问性和一致的键盘控制得到维护。

vue
<script setup lang="ts">
import { NavigationMenuItem, NavigationMenuList, NavigationMenuRoot } from 'radix-vue'

// RouterLink should be injected by default if using `vue-router`
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuLink as-child>
          <RouterLink to="/">
            Home
          </RouterLink>
          <NavigationMenuLink />
        </NavigationMenuLink>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuLink
          :as="RouterLink"
          to="/about"
        >
          About
        </NavigationMenuLink>
      </NavigationMenuItem>
    </NavigationMenuList>
  </NavigationMenuRoot>
</template>

高级动画

我们公开--radix-navigation-menu-viewport-[width|height]data-motion['from-start'|'to-start'|'from-end'|'to-end']属性,允许您根据进入/退出方向动画Viewport大小和Content位置。

将这些与position: absolute;结合使用,您可以在项目之间移动时创建平滑的重叠动画效果。

vue
<script setup lang="ts">
import {
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from 'radix-vue'
</script>

<template>
  <NavigationMenuRoot>
    <NavigationMenuList>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item one</NavigationMenuTrigger>
        <NavigationMenuContent class="NavigationMenuContent">
          Item one content
        </NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Item two</NavigationMenuTrigger>
        <NavigationMenuContent class="NavigationMenuContent">
          Item two content
        </NavigationMenuContent>
      </NavigationMenuItem>
    </NavigationMenuList>

    <NavigationMenuViewport class="NavigationMenuViewport" />
  </NavigationMenuRoot>
</template>
css
/* styles.css */
.NavigationMenuContent {
  position: absolute;
  top: 0;
  left: 0;
  animation-duration: 250ms;
  animation-timing-function: ease;
}
.NavigationMenuContent[data-motion="from-start"] {
  animation-name: enterFromLeft;
}
.NavigationMenuContent[data-motion="from-end"] {
  animation-name: enterFromRight;
}
.NavigationMenuContent[data-motion="to-start"] {
  animation-name: exitToLeft;
}
.NavigationMenuContent[data-motion="to-end"] {
  animation-name: exitToRight;
}

.NavigationMenuViewport {
  position: relative;
  width: var(--radix-navigation-menu-viewport-width);
  height: var(--radix-navigation-menu-viewport-height);
  transition: width, height, 250ms ease;
}

@keyframes enterFromRight {
  from {
    opacity: 0;
    transform: translateX(200px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes enterFromLeft {
  from {
    opacity: 0;
    transform: translateX(-200px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes exitToRight {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(200px);
  }
}

@keyframes exitToLeft {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(-200px);
  }
}

可访问性

符合navigation 角色要求

与菜单栏的区别

NavigationMenu不应该与menubar混淆,尽管这个原语在口语中共享了menu这个名字来指代一组导航链接,但它没有使用WAI-ARIA menu角色。这是因为menumenubars的行为类似于最常出现在桌面应用程序窗口中的原生操作系统菜单,因此它们具有复合焦点管理和首字母导航等复杂功能。

这些功能通常被认为对网站导航来说是不必要的,最糟糕的是,这些功能可能会让熟悉既定网站模式的用户感到困惑。

有关更多信息,请参阅W3C的公开导航菜单示例。

对于菜单中的所有导航链接,使用NavigationMenuLink非常重要,这不仅适用于主列表,还适用于通过NavigationMenuContent呈现的任何内容。这将确保一致的键盘交互和可访问性,同时还可以访问active道具来设置aria-current和活动样式。有关使用第三方路由组件的更多信息,请参阅此示例

键盘交互

描述
空格回车
当焦点在NavigationMenuTrigger上时,打开内容。
Tab
将焦点移动到下一个可聚焦元素。
向下箭头
horizontal且焦点在打开的NavigationMenuTrigger上时,将焦点移动到NavigationMenuContent中。
将焦点移动到下一个NavigationMenuTriggerNavigationMenuLink
向上箭头
将焦点移动到上一个NavigationMenuTriggerNavigationMenuLink
向右箭头向左箭头
vertical且焦点在打开的NavigationMenuTrigger上时,将焦点移动到其NavigationMenuContent中。
将焦点移动到下一个/上一个NavigationMenuTriggerNavigationMenuLink
HomeEnd
将焦点移动到第一个/最后一个NavigationMenu.TriggerNavigationMenu.Link
Esc
关闭打开的NavigationMenu.Content并将焦点移动到其NavigationMenu.Trigger