Skip to main content

VMenu

The VMenu component creates contextual menus that overlay content. It’s built on top of VOverlay and provides keyboard navigation, nested menu support, and flexible positioning.

Basic Usage

<template>
  <v-menu>
    <template #activator="{ props }">
      <v-btn v-bind="props">Open Menu</v-btn>
    </template>
    <v-list>
      <v-list-item>Option 1</v-list-item>
      <v-list-item>Option 2</v-list-item>
      <v-list-item>Option 3</v-list-item>
    </v-list>
  </v-menu>
</template>

Props

modelValue
boolean
Controls the visibility of the menu. Use with v-model.
id
string
Custom ID for the menu element. Auto-generated if not provided.
submenu
boolean
default:"false"
Indicates this menu is a submenu of another menu. Changes arrow key behavior.
activator
Element or selector string to use as the activator.
activatorProps
object
Props to bind to the activator element.
openDelay
number
default:"300"
Delay in milliseconds before the menu opens.
closeDelay
number
default:"250"
Delay in milliseconds before the menu closes.
closeOnContentClick
boolean
default:"true"
Whether to close the menu when clicking on its content.
location
string
Position where the menu appears relative to activator. Default is ‘bottom’ for menus, ‘end’ for submenus.
locationStrategy
'static' | 'connected'
default:"'connected'"
Strategy for positioning the menu.
scrollStrategy
'none' | 'close' | 'block' | 'reposition'
default:"'reposition'"
How the menu behaves when the page is scrolled.
offset
number | string | number[]
Offset of the menu from the activator.
scrim
boolean
default:"false"
Whether to display an overlay scrim behind the menu.
transition
string | object
Custom transition component for the menu appearance.
persistent
boolean
default:"false"
Whether clicking outside the menu closes it.
disabled
boolean
default:"false"
Disables the menu activator.
captureFocus
boolean
default:"true"
Whether to trap focus within the menu when open.
retainFocus
boolean
default:"true"
Whether to return focus to activator when menu closes.

Events

update:modelValue
(value: boolean) => void
Emitted when the menu is opened or closed.

Slots

activator
{ props: object, isActive: boolean }
Slot for the element that triggers the menu. The props must be bound to the activator element.
default
Content displayed inside the menu overlay.

Controlled Menu

<template>
  <v-menu v-model="menu">
    <template #activator="{ props }">
      <v-btn v-bind="props">Menu</v-btn>
    </template>
    <v-list>
      <v-list-item @click="menu = false">Close</v-list-item>
    </v-list>
  </v-menu>
</template>

<script setup>
import { ref } from 'vue'

const menu = ref(false)
</script>

Nested Menus

<template>
  <v-menu>
    <template #activator="{ props }">
      <v-btn v-bind="props">Menu</v-btn>
    </template>
    <v-list>
      <v-list-item>Option 1</v-list-item>
      <v-menu submenu>
        <template #activator="{ props }">
          <v-list-item v-bind="props">More Options</v-list-item>
        </template>
        <v-list>
          <v-list-item>Sub Option 1</v-list-item>
          <v-list-item>Sub Option 2</v-list-item>
        </v-list>
      </v-menu>
    </v-list>
  </v-menu>
</template>

Custom Position

<template>
  <v-menu location="end">
    <template #activator="{ props }">
      <v-btn v-bind="props">Right Menu</v-btn>
    </template>
    <v-list>
      <v-list-item>Option 1</v-list-item>
    </v-list>
  </v-menu>
</template>

Persistent Menu

<template>
  <v-menu persistent :close-on-content-click="false">
    <template #activator="{ props }">
      <v-btn v-bind="props">Persistent Menu</v-btn>
    </template>
    <v-card>
      <v-card-text>
        This menu won't close on outside clicks
      </v-card-text>
    </v-card>
  </v-menu>
</template>

Keyboard Navigation

The menu component includes built-in keyboard navigation:
  • Arrow Down: Focus next menu item
  • Arrow Up: Focus previous menu item
  • Enter: Activate focused item (when closeOnContentClick is false)
  • Tab: Move through focusable elements
  • Escape: Close menu
  • Arrow Left/Right: Navigate submenus (in RTL-aware manner)

Accessibility

The menu automatically sets ARIA attributes:
  • aria-haspopup="menu" on the activator
  • aria-expanded reflects the open/closed state
  • aria-controls and aria-owns link to the menu ID
  • Focus management for keyboard navigation

Examples

<template>
  <v-menu>
    <template #activator="{ props }">
      <v-btn icon v-bind="props">
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </template>
    <v-list>
      <v-list-item prepend-icon="mdi-pencil">Edit</v-list-item>
      <v-list-item prepend-icon="mdi-delete">Delete</v-list-item>
    </v-list>
  </v-menu>
</template>

Offset Menu

<template>
  <v-menu :offset="[0, 10]">
    <template #activator="{ props }">
      <v-btn v-bind="props">Menu</v-btn>
    </template>
    <v-list>
      <v-list-item>Option 1</v-list-item>
    </v-list>
  </v-menu>
</template>

Build docs developers (and LLMs) love