跳至内容

上下文菜单

显示位于指针处的菜单,由右键单击或长按触发。
右键单击此处。
vue
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { ref } from 'vue'
import {
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuItemIndicator,
  ContextMenuLabel,
  ContextMenuPortal,
  ContextMenuRadioGroup,
  ContextMenuRadioItem,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from 'radix-vue'

const checkboxOne = ref(false)
const checkboxTwo = ref(false)
const person = ref('pedro')

function handleClick() {
  // eslint-disable-next-line no-alert
  alert('hello!')
}
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger
      as-child
      class="block border-2 border-white border-dashed text-white rounded text-[15px] select-none py-[45px] w-[300px] text-center"
    >
      <span> Right click here. </span>
    </ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent
        class="min-w-[220px] z-30 bg-white outline-none rounded-md p-[5px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
        :side-offset="5"
      >
        <ContextMenuItem
          value="New Tab"
          class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
          @click="handleClick"
        >
          New Tab <div
            class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
          >
            ⌘+T
          </div>
        </ContextMenuItem>
        <ContextMenuSub>
          <ContextMenuSubTrigger
            value="more toolsz"
            class="group w-full text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[state=open]:bg-green4 data-[state=open]:text-grass11 data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1 data-[highlighted]:data-[state=open]:bg-green9 data-[highlighted]:data-[state=open]:text-green1"
          >
            More Tools <div
              class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
            >
              <Icon icon="radix-icons:chevron-right" />
            </div>
          </ContextMenuSubTrigger>
          <ContextMenuPortal>
            <ContextMenuSubContent
              class="min-w-[220px] z-30 outline-none bg-white rounded-md p-[5px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
              :side-offset="2"
              :align-offset="-5"
            >
              <ContextMenuItem
                class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Save Page As… <div
                  class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                >
                  ⌘+S
                </div>
              </ContextMenuItem>
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Create Shortcut…
              </ContextMenuItem>
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Name Window…
              </ContextMenuItem>
              <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Developer Tools
              </ContextMenuItem>
            </ContextMenuSubContent>
          </ContextMenuPortal>
        </ContextMenuSub>
        <ContextMenuItem
          value="New Window"
          class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
        >
          New Window <div
            class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
          >
            ⌘+N
          </div>
        </ContextMenuItem>
        <ContextMenuItem
          value="New Private Window"
          class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
          disabled
        >
          New Private Window <div
            class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
          >
            ⇧+⌘+N
          </div>
        </ContextMenuItem>
        <ContextMenuSub>
          <ContextMenuSubTrigger
            value="more tools"
            class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none w-full outline-none data-[state=open]:bg-green4 data-[state=open]:text-grass11 data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1 data-[highlighted]:data-[state=open]:bg-green9 data-[highlighted]:data-[state=open]:text-green1"
          >
            More Tools <div
              class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
            >
              <Icon icon="radix-icons:chevron-right" />
            </div>
          </ContextMenuSubTrigger>
          <ContextMenuPortal>
            <ContextMenuSubContent
              class="min-w-[220px] z-30 outline-none bg-white rounded-md p-[5px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
              :side-offset="2"
              :align-offset="-5"
            >
              <ContextMenuItem
                class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Save Page As… <div
                  class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                >
                  ⌘+S
                </div>
              </ContextMenuItem>
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Create Shortcut…
              </ContextMenuItem>
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Name Window…
              </ContextMenuItem>
              <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Developer Tools
              </ContextMenuItem>
              <ContextMenuSub>
                <ContextMenuSubTrigger
                  value="more toolsz"
                  class="group w-full text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[state=open]:bg-green4 data-[state=open]:text-grass11 data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1 data-[highlighted]:data-[state=open]:bg-green9 data-[highlighted]:data-[state=open]:text-green1"
                >
                  More Tools <div
                    class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                  >
                    <Icon icon="radix-icons:chevron-right" />
                  </div>
                </ContextMenuSubTrigger>
                <ContextMenuPortal>
                  <ContextMenuSubContent
                    class="min-w-[220px] z-30 outline-none bg-white rounded-md p-[5px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
                    :side-offset="2"
                    :align-offset="-5"
                  >
                    <ContextMenuItem
                      class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                    >
                      Save Page As… <div
                        class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                      >
                        ⌘+S
                      </div>
                    </ContextMenuItem>
                    <ContextMenuItem
                      class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                    >
                      Create Shortcut…
                    </ContextMenuItem>
                    <ContextMenuItem
                      class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                    >
                      Name Window…
                    </ContextMenuItem>
                    <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
                    <ContextMenuItem
                      class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                    >
                      Developer Tools
                    </ContextMenuItem>
                    <ContextMenuSub>
                      <ContextMenuSubTrigger
                        value="more toolsz"
                        class="group w-full text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[state=open]:bg-green4 data-[state=open]:text-grass11 data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1 data-[highlighted]:data-[state=open]:bg-green9 data-[highlighted]:data-[state=open]:text-green1"
                      >
                        More Tools <div
                          class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                        >
                          <Icon icon="radix-icons:chevron-right" />
                        </div>
                      </ContextMenuSubTrigger>
                      <ContextMenuPortal>
                        <ContextMenuSubContent
                          class="min-w-[220px] z-30 outline-none bg-white rounded-md p-[5px] shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
                          :side-offset="2"
                          :align-offset="-5"
                        >
                          <ContextMenuItem
                            class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                          >
                            Save Page As… <div
                              class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
                            >
                              ⌘+S
                            </div>
                          </ContextMenuItem>
                          <ContextMenuItem
                            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                          >
                            Create Shortcut…
                          </ContextMenuItem>
                          <ContextMenuItem
                            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                          >
                            Name Window…
                          </ContextMenuItem>
                          <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
                          <ContextMenuItem
                            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
                          >
                            Developer Tools
                          </ContextMenuItem>
                        </ContextMenuSubContent>
                      </ContextMenuPortal>
                    </ContextMenuSub>
                  </ContextMenuSubContent>
                </ContextMenuPortal>
              </ContextMenuSub>
              <ContextMenuItem
                class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
              >
                Developer Tools
              </ContextMenuItem>
            </ContextMenuSubContent>
          </ContextMenuPortal>
        </ContextMenuSub>
        <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
        <ContextMenuCheckboxItem
          v-model="checkboxOne"
          class="group text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
        >
          <ContextMenuItemIndicator class="absolute left-0 w-[25px] inline-flex items-center justify-center">
            <Icon icon="radix-icons:check" />
          </ContextMenuItemIndicator> Show Bookmarks <div
            class="ml-auto pl-[20px] text-mauve11 group-data-[highlighted]:text-white group-data-[disabled]:text-mauve8"
          >
            ⌘+B
          </div>
        </ContextMenuCheckboxItem>
        <ContextMenuCheckboxItem
          v-model="checkboxTwo"
          class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
        >
          <ContextMenuItemIndicator class="absolute left-0 w-[25px] inline-flex items-center justify-center">
            <Icon icon="radix-icons:check" />
          </ContextMenuItemIndicator> Show Full URLs
        </ContextMenuCheckboxItem>
        <ContextMenuSeparator class="h-[1px] bg-green6 m-[5px]" />
        <ContextMenuLabel class="pl-[25px] text-xs leading-[25px] text-mauve11">
          People
        </ContextMenuLabel>
        <ContextMenuRadioGroup v-model="person">
          <ContextMenuRadioItem
            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
            value="pedro"
          >
            <ContextMenuItemIndicator class="absolute left-0 w-[25px] inline-flex items-center justify-center">
              <Icon icon="radix-icons:dot-filled" />
            </ContextMenuItemIndicator> Pedro Duarte
          </ContextMenuRadioItem>
          <ContextMenuRadioItem
            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] px-[5px] relative pl-[25px] select-none outline-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1"
            value="colm"
          >
            <ContextMenuItemIndicator class="absolute left-0 w-[25px] inline-flex items-center justify-center">
              <Icon icon="radix-icons:dot-filled" />
            </ContextMenuItemIndicator> Colm Tuite
          </ContextMenuRadioItem>
        </ContextMenuRadioGroup>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

特性

  • 支持具有可配置阅读方向的子菜单。
  • 支持项目、标签、项目组。
  • 支持可选中项目(单个或多个),并可选地包含未确定状态。
  • 支持模态和非模态模式。
  • 自定义侧边、对齐方式、偏移量、碰撞处理。
  • 完全管理焦点。
  • 完整的键盘导航。
  • 支持输入提示。
  • 关闭和分层行为高度可定制。
  • 在触控设备上使用长按触发

安装

从命令行安装组件。

sh
$ npm add radix-vue

结构

导入所有部分并将它们拼凑在一起。

vue
<script setup lang="ts">
import {
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuItemIndicator,
  ContextMenuLabel,
  ContextMenuPortal,
  ContextMenuRadioGroup,
  ContextMenuRadioItem,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger />

    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuLabel />
        <ContextMenuItem />

        <ContextMenuGroup>
          <ContextMenuItem />
        </ContextMenuGroup>

        <ContextMenuCheckboxItem>
          <ContextMenuItemIndicator />
        </ContextMenuCheckboxItem>

        <ContextMenuRadioGroup>
          <ContextMenuRadioItem>
            <ContextMenuItemIndicator />
          </ContextMenuRadioItem>
        </ContextMenuRadioGroup>

        <ContextMenuSub>
          <ContextMenuSubTrigger />
          <ContextMenuPortal>
            <ContextMenuSubContent />
          </ContextMenuPortal>
        </ContextMenuSub>

        <ContextMenuSeparator />
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

API 参考

遵循 菜单 WAI-ARIA 设计模式,并使用 移动 tabindex 来管理菜单项之间的焦点移动。

包含上下文菜单的所有部分。

属性默认值类型
dir
'ltr' | 'rtl'

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

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

modal
true
boolean

下拉菜单的模态性。

当设置为 true 时,将禁用与外部元素的交互,并且只有菜单内容对屏幕阅读器可见。

发射有效载荷
update:open
[payload: boolean]

当子菜单的打开状态发生变化时调用的事件处理程序。

触发器

打开上下文菜单的区域。将它包裹在您希望在右键单击(或使用相关的键盘快捷键)时从其打开上下文菜单的目标周围。

属性默认值类型
as
'span'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

disabled
false
boolean

true 时,上下文菜单在右键单击时不会打开。

请注意,这也会恢复本机上下文菜单。

数据属性
[data-state]"open" | "closed"

传送门

使用时,将内容部分传送至 body

属性默认值类型
disabled
boolean

禁用传送并内联渲染组件

reference

forceMount
boolean

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

to
string | HTMLElement

Vue 本机传送组件属性 :to

reference

内容

在打开的上下文菜单中弹出的组件。

属性默认值类型
alignOffset
0
number

startend 对齐选项偏移的像素数。

as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

avoidCollisions
true
boolean

true 时,会覆盖侧边和对齐首选项,以防止与边界边缘发生碰撞。

collisionBoundary
[]
Element | (Element | null)[] | null

用作碰撞边界的元素。默认情况下,这是视窗,但您可以提供要在其中包含的其他元素。

collisionPadding
0
number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>

距离边界边缘的像素数,在该距离处应发生碰撞检测。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。

forceMount
boolean

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

hideWhenDetached
false
boolean

当触发器完全被遮挡时,是否隐藏内容。

loop
boolean

true 时,键盘导航将从最后一个项目循环到第一个项目,反之亦然。

prioritizePosition
boolean

强制内容位于视窗内。

可能会与引用元素重叠,这可能不是期望的结果。

sticky
'partial'
'partial' | 'always'

对齐轴上的粘性行为。partial 将使内容保持在边界内,只要触发器至少部分在边界内,而 “always” 将始终使内容保持在边界内,而不管其他因素。

发射有效载荷
closeAutoFocus
[event: Event]

在关闭时自动聚焦时调用的事件处理程序。可以阻止。

escapeKeyDown
[event: KeyboardEvent]

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

focusOutside
[event: FocusOutsideEvent]

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

interactOutside
[event: PointerDownOutsideEvent | FocusOutsideEvent]

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

pointerDownOutside
[event: PointerDownOutsideEvent]

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

数据属性
[data-state]"open" | "closed"
[data-side]"left" | "right" | "bottom" | "top"
[data-align]"start" | "end" | "center"
CSS 变量描述
--radix-context-menu-content-transform-origin
从内容和箭头位置/偏移量计算的 transform-origin
--radix-context-menu-content-available-width
触发器和边界边缘之间的剩余宽度
--radix-context-menu-content-available-height
触发器和边界边缘之间的剩余高度
--radix-context-menu-trigger-width
触发器的宽度
--radix-context-menu-trigger-height
触发器的高度

箭头

一个可选的箭头元素,与子菜单一起渲染。这可以用于帮助在视觉上将触发项目与 ContextMenu.Content 关联起来。必须渲染在 ContextMenu.Content 内。

属性默认值类型
as
'svg'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

height
5
number

箭头的像素高度。

width
10
number

箭头的像素宽度。

项目

包含上下文菜单项目的组件。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

disabled
boolean

true 时,会阻止用户与项目交互。

textValue
字符串

用于类型提前的可选文本。默认情况下,类型提前行为将使用项目的 .textContent
当内容很复杂,或者你在里面有非文本内容时,使用它。

发射有效载荷
select
[event: Event]

当用户选择一个项目(通过鼠标或键盘)时调用的事件处理程序。
在该处理程序中调用 event.preventDefault 将阻止菜单在选择该项目时关闭。

数据属性
[data-highlighted]高亮时出现
[data-disabled]禁用时出现

分组

用于对多个 ContextMenu.Item 进行分组。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

标签

用于渲染标签。它不会使用箭头键可聚焦。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

CheckboxItem

一个可以像复选框一样控制和渲染的项目。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

checked
false | true | 'indeterminate'

项目的受控选中状态。可以用作 v-model:checked

disabled
boolean

true 时,会阻止用户与项目交互。

textValue
字符串

用于类型提前的可选文本。默认情况下,类型提前行为将使用项目的 .textContent
当内容很复杂,或者你在里面有非文本内容时,使用它。

发射有效载荷
select
[event: Event]

当用户选择一个项目(通过鼠标或键盘)时调用的事件处理程序。
在该处理程序中调用 event.preventDefault 将阻止菜单在选择该项目时关闭。

update:checked
[payload: boolean]

选中状态改变时调用的事件处理程序。

数据属性
[data-state]"checked" | "unchecked" | "indeterminate"
[data-highlighted]高亮时出现
[data-disabled]禁用时出现

RadioGroup

用于对多个 ContextMenu.RadioItem 进行分组。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

modelValue
字符串

组中选定项目的 value。

发射有效载荷
update:modelValue
[payload: string]

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

RadioItem

一个可以像单选按钮一样控制和渲染的项目。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

disabled
boolean

true 时,会阻止用户与项目交互。

textValue
字符串

用于类型提前的可选文本。默认情况下,类型提前行为将使用项目的 .textContent
当内容很复杂,或者你在里面有非文本内容时,使用它。

value*
字符串

项目的唯一值。

发射有效载荷
select
[event: Event]

当用户选择一个项目(通过鼠标或键盘)时调用的事件处理程序。
在该处理程序中调用 event.preventDefault 将阻止菜单在选择该项目时关闭。

数据属性
[data-state]"checked" | "unchecked" | "indeterminate"
[data-highlighted]高亮时出现
[data-disabled]禁用时出现

ItemIndicator

当父 ContextMenu.CheckboxItemContextMenu.RadioItem 被选中时渲染。你可以直接样式化这个元素,或者你可以用它作为一个包装器来放入一个图标,或者两者都用。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

forceMount
boolean

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

数据属性
[data-state]"checked" | "unchecked" | "indeterminate"

Separator

用于在上下文菜单中视觉上分隔项目。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

Sub

包含子菜单的所有部分。

属性默认值类型
defaultOpen
boolean

子菜单在初始渲染时的打开状态。当你不需要控制它的打开状态时使用。

open
boolean

菜单的受控打开状态。可以用作 v-model:open

发射有效载荷
update:open
[payload: boolean]

当子菜单的打开状态发生变化时调用的事件处理程序。

插槽 (默认)有效载荷
open
boolean

当前打开状态

SubTrigger

一个打开子菜单的项目。必须渲染在 ContextMenu.Sub 内。

属性默认值类型
as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

disabled
boolean

true 时,会阻止用户与项目交互。

textValue
字符串

用于类型提前的可选文本。默认情况下,类型提前行为将使用项目的 .textContent
当内容很复杂,或者你在里面有非文本内容时,使用它。

数据属性
[data-state]"open" | "closed"
[data-highlighted]高亮时出现
[data-disabled]禁用时出现

SubContent

当子菜单打开时弹出的组件。必须渲染在 ContextMenu.Sub 内。

属性默认值类型
alignOffset
number

startend 对齐选项偏移的像素数。

arrowPadding
number

箭头和内容边缘之间的填充。如果你的内容有圆角,这将防止它溢出角。

as
'div'
AsTag | 组件

此组件应该呈现为的元素或组件。可以通过 asChild 覆盖。

asChild
boolean

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

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

avoidCollisions
boolean

true 时,会覆盖侧边和对齐首选项,以防止与边界边缘发生碰撞。

collisionBoundary
Element | (Element | null)[] | null

用作碰撞边界的元素。默认情况下,这是视窗,但您可以提供要在其中包含的其他元素。

collisionPadding
number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>

距离边界边缘的像素数,在该距离处应发生碰撞检测。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。

forceMount
boolean

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

hideWhenDetached
boolean

当触发器完全被遮挡时,是否隐藏内容。

loop
boolean

true 时,键盘导航将从最后一个项目循环到第一个项目,反之亦然。

prioritizePosition
boolean

强制内容位于视窗内。

可能会与引用元素重叠,这可能不是期望的结果。

sideOffset
number

触发器距离的像素数。

sticky
'partial' | 'always'

对齐轴上的粘性行为。partial 将使内容保持在边界内,只要触发器至少部分在边界内,而 “always” 将始终使内容保持在边界内,而不管其他因素。

updatePositionStrategy
'always' | 'optimized'

在每个动画帧上更新浮动元素位置的策略。

发射有效载荷
closeAutoFocus
[event: Event]

在关闭时自动聚焦时调用的事件处理程序。可以阻止。

entryFocus
[event: Event]
escapeKeyDown
[event: KeyboardEvent]

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

focusOutside
[event: FocusOutsideEvent]

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

interactOutside
[event: PointerDownOutsideEvent | FocusOutsideEvent]

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

openAutoFocus
[event: Event]

在打开时自动聚焦时调用的事件处理程序。可以阻止。

pointerDownOutside
[event: PointerDownOutsideEvent]

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

数据属性
[data-state]"open" | "closed"
[data-side]"left" | "right" | "bottom" | "top"
[data-align]"start" | "end" | "center"
CSS 变量描述
--radix-context-menu-content-transform-origin
从内容和箭头位置/偏移量计算的 transform-origin
--radix-context-menu-content-available-width
触发器和边界边缘之间的剩余宽度
--radix-context-menu-content-available-height
触发器和边界边缘之间的剩余高度
--radix-context-menu-trigger-width
触发器的宽度
--radix-context-menu-trigger-height
触发器的高度

示例

带有子菜单

你可以通过将 ContextMenuSub 与其部分组合来创建子菜单。

vue
<script setup lang="ts">
import {
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuLabel,
  ContextMenuPortal,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuSeparator />
        <ContextMenuSub>
          <ContextMenuSubTrigger>Sub menu →</ContextMenuSubTrigger>
          <ContextMenuPortal>
            <ContextMenuSubContent>
              <ContextMenuItem>Sub menu item</ContextMenuItem>
              <ContextMenuItem>Sub menu item</ContextMenuItem>
              <ContextMenuArrow />
            </ContextMenuSubContent>
          </ContextMenuPortal>
        </ContextMenuSub>
        <ContextMenuSeparator />
        <ContextMenuItem></ContextMenuItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

带有禁用项

你可以通过 data-disabled 属性为禁用的项目添加特殊样式。

vue
<script setup lang="ts">
import { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuRoot, ContextMenuTrigger } from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuItem
          class="ContextMenuItem"
          disabled
        >

        </ContextMenuItem>
        <ContextMenuItem class="ContextMenuItem">

        </ContextMenuItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>
css
/* styles.css */
.ContextMenuItem[data-disabled] {
  color: gainsboro;
}

带有分隔符

使用 Separator 部分在项目之间添加分隔符。

vue
<script setup lang="ts">
import {
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuPortal,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuSeparator />
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuSeparator />
        <ContextMenuItem></ContextMenuItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

带有标签

使用 Label 部分来帮助标记一个部分。

vue
<script setup lang="ts">
import {
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuLabel,
  ContextMenuPortal,
  ContextMenuRoot,
  ContextMenuTrigger,
} from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuLabel>Label</ContextMenuLabel>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuItem></ContextMenuItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

带有复选框项目

使用 CheckboxItem 部分添加一个可以选中 的项目。

vue
<script setup lang="ts">
import {
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuItemIndicator,
  ContextMenuPortal,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from 'radix-vue'
import { Icon } from '@iconify/vue'

const checked = ref(true)
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuItem></ContextMenuItem>
        <ContextMenuSeparator />
        <ContextMenuCheckboxItem v-model="checked">
          <ContextMenuItemIndicator>
            <Icon icon="radix-icons:check" />
          </ContextMenuItemIndicator>
          Checkbox item
        </ContextMenuCheckboxItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

带有单选按钮项目

使用 RadioGroupRadioItem 部分添加一个可以在其他项目中选中的项目。

vue
<script setup lang="ts">
import {
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuItemIndicator,
  ContextMenuPortal,
  ContextMenuRadioGroup,
  ContextMenuRadioItem,
  ContextMenuRoot,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from 'radix-vue'
import { Icon } from '@iconify/vue'

const color = ref('blue')
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuRadioGroup v-model="color">
          <ContextMenuRadioItem value="red">
            <ContextMenuItemIndicator>
              <Icon icon="radix-icons:check" />
            </ContextMenuItemIndicator>
            Red
          </ContextMenuRadioItem>
          <ContextMenuRadioItem value="blue">
            <ContextMenuItemIndicator>
              <Icon icon="radix-icons:check" />
            </ContextMenuItemIndicator>
            Blue
          </ContextMenuRadioItem>
          <ContextMenuRadioItem value="green">
            <ContextMenuItemIndicator>
              <Icon icon="radix-icons:check" />
            </ContextMenuItemIndicator>
            Green
          </ContextMenuRadioItem>
        </ContextMenuRadioGroup>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

带有复杂项目

你可以在 Item 部分添加额外的装饰性元素,例如图像。

vue
<script setup lang="ts">
import { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuRoot, ContextMenuTrigger } from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent>
        <ContextMenuItem>
          <img src="">
          Adolfo Hess
        </ContextMenuItem>
        <ContextMenuItem>
          <img src="">
          Miyah Myles
        </ContextMenuItem>
      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>

约束内容/子内容大小

你可能想要约束内容(或子内容)的宽度,使其与触发器(或子触发器)宽度一致。你可能还想要约束它的高度,使其不超过视窗。

我们公开了一些 CSS 自定义属性,例如 --radix-context-menu-trigger-width--radix-context-menu-content-available-height 来支持这一点。使用它们来约束内容尺寸。

vue
<script setup lang="ts">
import { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuRoot, ContextMenuTrigger } from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent class="ContextMenuContent">

      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>
css
/* styles.css */
.ContextMenuContent {
  width: var(--radix-context-menu-trigger-width);
  max-height: var(--radix-context-menu-content-available-height);
}

原点感知动画

我们公开了一个 CSS 自定义属性 --radix-context-menu-content-transform-origin。使用它根据 sidesideOffsetalignalignOffset 和任何碰撞来从其计算出的原点动画内容。

vue
<script setup lang="ts">
import { ContextMenuContent, ContextMenuPortal, ContextMenuRoot, ContextMenuTrigger } from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent class="ContextMenuContent">

      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>
css
/* styles.css */
.ContextMenuContent {
  transform-origin: var(--radix-context-menu-content-transform-origin);
  animation: scaleIn 0.5s ease-out;
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

碰撞感知动画

我们公开 data-sidedata-align 属性。它们的 value 将在运行时改变,以反映碰撞。使用它们创建碰撞和方向感知动画。

vue
<script setup lang="ts">
import { ContextMenuContent, ContextMenuPortal, ContextMenuRoot, ContextMenuTrigger } from 'radix-vue'
</script>

<template>
  <ContextMenuRoot>
    <ContextMenuTrigger></ContextMenuTrigger>
    <ContextMenuPortal>
      <ContextMenuContent class="ContextMenuContent">

      </ContextMenuContent>
    </ContextMenuPortal>
  </ContextMenuRoot>
</template>
css
/* styles.css */
.ContextMenuContent {
  animation-duration: 0.6s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.ContextMenuContent[data-side="top"] {
  animation-name: slideUp;
}
.ContextMenuContent[data-side="bottom"] {
  animation-name: slideDown;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

可访问性

使用 roving tabindex 来管理菜单项之间的焦点移动。

键盘交互

描述
空格
激活聚焦的项目。
回车
激活聚焦的项目。
向下箭头
将焦点移动到下一个项目。
向上箭头
将焦点移动到上一个项目。
右箭头左箭头
当焦点在 ContextMenu.SubTrigger 上时,根据阅读方向打开或关闭子菜单。
Esc
关闭上下文菜单