Меню v-menu

Компонент v-menu в Vuetify представляет собой всплывающее меню, которое может быть привязано к любому элементу интерфейса, например кнопке, текстовому полю или изображению. Он используется для создания контекстных меню, выпадающих списков и панелей управления. Основная структура v-menu включает три ключевых элемента:

  • activator — элемент, который инициирует открытие меню.
  • content — непосредственно содержимое меню, обычно это v-list или v-card.
  • props — свойства для управления поведением меню (например, позиционирование, открытие по наведению, задержка закрытия).

Простейший пример:

<v-menu>
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Открыть меню</v-btn>
  </template>
  <v-list>
    <v-list-item>
      <v-list-item-title>Элемент 1</v-list-item-title>
    </v-list-item>
    <v-list-item>
      <v-list-item-title>Элемент 2</v-list-item-title>
    </v-list-item>
  </v-list>
</v-menu>

Здесь activator использует v-slot с объектами on и attrs для передачи событий и атрибутов кнопке, что обеспечивает корректное открытие меню.


Управление состоянием меню

Меню можно открывать и закрывать программно через v-model. Это позволяет динамически контролировать отображение меню в зависимости от состояния приложения:

<v-menu v-model="menuVisible">
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Меню</v-btn>
  </template>
  <v-list>
    <v-list-item @click="menuVisible = false">
      <v-list-item-title>Закрыть меню</v-list-item-title>
    </v-list-item>
  </v-list>
</v-menu>

<script>
export default {
  data() {
    return {
      menuVisible: false,
    };
  },
};
</script>

Свойство v-model связывает видимость меню с переменной menuVisible. При изменении переменной меню автоматически открывается или закрывается.


Позиционирование и поведение меню

v-menu поддерживает гибкую настройку позиционирования через свойства:

  • top, bottom, left, right — положение относительно activator.
  • offset-x, offset-y — смещение по оси X и Y.
  • nudge-width, nudge-height — дополнительная подстройка размеров.
  • origin — точка, от которой начинается анимация раскрытия.

Пример меню, раскрывающегося справа снизу с небольшим смещением:

<v-menu bottom right offset-x="10" offset-y="5">
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Параметры</v-btn>
  </template>
  <v-list>
    <v-list-item>
      <v-list-item-title>Настройка 1</v-list-item-title>
    </v-list-item>
    <v-list-item>
      <v-list-item-title>Настройка 2</v-list-item-title>
    </v-list-item>
  </v-list>
</v-menu>

С помощью этих параметров можно точно подстраивать меню под интерфейс, избегая перекрытия других элементов.


Встроенные триггеры и события

v-menu предоставляет несколько способов взаимодействия:

  • open-on-hover — открытие при наведении курсора.
  • close-on-content-click — автоматическое закрытие после клика по элементу меню.
  • close-delay, open-delay — задержка перед закрытием или открытием, полезна для сложных UI с множественными элементами.
  • События @update:model-value или @click:outside позволяют реагировать на изменение состояния меню или клики вне него.

Пример открытия меню при наведении с задержкой:

<v-menu open-on-hover close-delay="200">
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Наведи на меня</v-btn>
  </template>
  <v-list>
    <v-list-item>
      <v-list-item-title>Элемент A</v-list-item-title>
    </v-list-item>
    <v-list-item>
      <v-list-item-title>Элемент B</v-list-item-title>
    </v-list-item>
  </v-list>
</v-menu>

Меню с произвольным содержимым

v-menu не ограничивается списками. Внутри меню можно использовать любые компоненты Vuetify: формы, карточки, таблицы. Это делает меню мощным инструментом для создания интерактивных панелей и сложных интерфейсов.

Пример меню с формой:

<v-menu v-model="formMenu">
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Форма</v-btn>
  </template>
  <v-card>
    <v-card-title>Вход в систему</v-card-title>
    <v-card-text>
      <v-text-field label="Email"></v-text-field>
      <v-text-field label="Пароль" type="password"></v-text-field>
    </v-card-text>
    <v-card-actions>
      <v-btn color="primary" @click="formMenu = false">Войти</v-btn>
    </v-card-actions>
  </v-card>
</v-menu>

Адаптивное и мобильное меню

v-menu автоматически поддерживает адаптивность, но для мобильных устройств рекомендуется использовать max-width и transition для плавного раскрытия:

<v-menu max-width="300" transition="slide-y-transition">
  <template v-slot:activator="{ on, attrs }">
    <v-btn v-bind="attrs" v-on="on">Мобильное меню</v-btn>
  </template>
  <v-list>
    <v-list-item>
      <v-list-item-title>Опция 1</v-list-item-title>
    </v-list-item>
    <v-list-item>
      <v-list-item-title>Опция 2</v-list-item-title>
    </v-list-item>
  </v-list>
</v-menu>

Комбинирование с другими компонентами

Меню удобно интегрируется с компонентами v-btn, v-icon, v-avatar и даже v-data-table. Это позволяет создавать контекстные действия прямо внутри таблиц или списков. Также v-menu хорошо сочетается с v-tooltip, если требуется отображать подсказки поверх или рядом с активатором.


Практические рекомендации

  • Использовать v-slot:activator для передачи событий и атрибутов.
  • Управлять видимостью через v-model для программного контроля.
  • Настраивать позиционирование с помощью offset и origin.
  • Для сложного контента использовать v-card вместо v-list.
  • На мобильных устройствах устанавливать max-width и переходы для плавного UX.
  • Для меню с большим количеством элементов применять виртуализацию или деление на группы.

Эти принципы обеспечивают гибкость и надежность при создании интерфейсов с использованием v-menu в Vuetify.