QMenu контекстные меню

Компонент QMenu представляет собой контекстное или всплывающее меню, которое может быть привязано к любому элементу на странице. Основная задача QMenu — предоставление пользователю набора действий или опций, связанных с конкретным элементом интерфейса. В Quasar меню строится через сочетание компонентов QMenu и QList, что позволяет создавать гибкие и настраиваемые контекстные меню.

<q-btn label="Открыть меню" ref="menuBtn" @click="menu = true" />
<q-menu v-model="menu" anchor="bottom left" self="top left">
  <q-list>
    <q-item clickable v-ripple @click="action1">
      <q-item-section>Действие 1</q-item-section>
    </q-item>
    <q-item clickable v-ripple @click="action2">
      <q-item-section>Действие 2</q-item-section>
    </q-item>
  </q-list>
</q-menu>
  • v-model управляет состоянием меню (открыто/закрыто).
  • anchor определяет точку привязки меню относительно родительского элемента.
  • self задаёт точку, которая будет выравниваться по anchor.
  • v-ripple добавляет эффект нажатия для элементов меню.

Привязка меню к элементу

Для создания контекстного меню, привязанного к конкретной кнопке или любому другому элементу, используется директива ref и событие @click или @contextmenu.

<div @contextmenu.prevent="menu = true; $refs.menuBtn = $event">
  Клик правой кнопкой для открытия меню
</div>
<q-menu v-model="menu" :context-menu="$refs.menuBtn">
  <q-list>
    <q-item clickable v-ripple @click="editItem">
      <q-item-section>Редактировать</q-item-section>
    </q-item>
    <q-item clickable v-ripple @click="deleteItem">
      <q-item-section>Удалить</q-item-section>
    </q-item>
  </q-list>
</q-menu>
  • @contextmenu.prevent предотвращает стандартное системное меню.
  • :context-menu привязывает меню к событию мыши и позиции курсора.

Использование QMenu с динамическими данными

Часто требуется строить меню на основе массива данных. Для этого используется директива v-for:

<q-menu v-model="menu">
  <q-list>
    <q-item v-for="item in menuItems" :key="item.label" clickable v-ripple @click="item.action">
      <q-item-section>{{ item.label }}</q-item-section>
    </q-item>
  </q-list>
</q-menu>
data() {
  return {
    menu: false,
    menuItems: [
      { label: 'Сохранить', action: this.saveFile },
      { label: 'Открыть', action: this.openFile },
      { label: 'Закрыть', action: this.closeFile }
    ]
  }
}
  • Позволяет легко управлять элементами меню и их действиями через один массив.
  • Упрощает поддержку и расширение меню без изменения разметки.

Настройка визуального оформления

QMenu поддерживает множество параметров для стилизации:

  • transition-show / transition-hide — задают анимацию открытия и закрытия.
  • max-height / max-width — ограничивают размеры меню.
  • cover — позволяет меню перекрывать элемент, к которому оно привязано.
<q-menu v-model="menu" transition-show="scale" transition-hide="fade" max-height="300px">
  <q-list>
    <q-item clickable v-ripple @click="download">
      <q-item-section>Скачать</q-item-section>
    </q-item>
  </q-list>
</q-menu>
  • scale и fade — стандартные переходы Quasar, обеспечивающие плавное открытие и закрытие меню.

Вложенные и разделённые меню

Для создания подменю можно использовать QItem с QMenu внутри:

<q-menu v-model="menu">
  <q-list>
    <q-item clickable v-ripple>
      <q-item-section>Файл</q-item-section>
      <q-menu auto-close>
        <q-list>
          <q-item clickable @click="newFile">
            <q-item-section>Новый</q-item-section>
          </q-item>
          <q-item clickable @click="openFile">
            <q-item-section>Открыть</q-item-section>
          </q-item>
        </q-list>
      </q-menu>
    </q-item>
  </q-list>
</q-menu>
  • auto-close автоматически закрывает подменю после выбора пункта.
  • Вложенные меню создают удобные многоуровневые интерфейсы без сложной логики.

Управление событиями и взаимодействием

QMenu предоставляет события для более точного контроля:

  • @show / @hide — срабатывают при открытии или закрытии меню.
  • @before-show / @before-hide — позволяют отменить действие.
methods: {
  onMenuShow() {
    console.log('Меню открыто');
  },
  onMenuHide() {
    console.log('Меню закрыто');
  }
}
<q-menu v-model="menu" @show="onMenuShow" @hide="onMenuHide">
  ...
</q-menu>

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

  • Использовать v-model для управления видимостью меню, чтобы избежать конфликтов при динамических данных.
  • Всегда добавлять v-ripple для интерактивных элементов, чтобы пользователь получал визуальную обратную связь.
  • Для контекстных меню применять @contextmenu.prevent, чтобы не открывалось стандартное меню браузера.
  • Поддерживать единый массив данных для элементов меню для упрощения расширения и модификации.
  • Вложенные меню использовать умеренно, чтобы интерфейс оставался понятным и не перегруженным.

Совместимость и адаптивность

QMenu корректно работает на мобильных устройствах и поддерживает сенсорное управление. Параметры cover и offset позволяют адаптировать меню под различные размеры экрана и положение элементов.

<q-menu v-model="menu" cover :offset="[10, 20]">
  <q-list>
    <q-item clickable @click="share">
      <q-item-section>Поделиться</q-item-section>
    </q-item>
  </q-list>
</q-menu>
  • offset задаёт смещение меню по горизонтали и вертикали относительно элемента привязки.
  • Упрощает точное позиционирование в сложных макетах.

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