Диалоговые окна v-dialog

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

Ключевой особенностью является управление видимостью через привязку к v-model, что позволяет динамически показывать и скрывать окно.

<template>
  <v-dialog v-model="dialog" max-width="500">
    <v-card>
      <v-card-title class="headline">Заголовок окна</v-card-title>
      <v-card-text>
        Содержимое диалогового окна.
      </v-card-text>
      <v-card-actions>
        <v-btn color="primary" text @click="dialog = false">Закрыть</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialog: false
    }
  }
}
</script>

В этом примере dialog контролирует состояние окна, а атрибут max-width ограничивает его ширину.


Управление открытием и закрытием

v-dialog поддерживает два основных способа управления: через v-model и через события.

  • v-model: основной способ управления состоянием окна.
  • События @input и @click:outside: позволяют отслеживать открытие и закрытие, а также закрывать окно при клике вне его области.
<v-dialog v-model="dialog" @click:outside="dialog = false">
  <v-card>
    <v-card-title>Модальное окно</v-card-title>
    <v-card-actions>
      <v-btn text @click="dialog = false">Закрыть</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>

Событие click:outside полезно для реализации поведения «клик вне окна — закрыть».


Настройка размеров и позиционирования

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

  • max-width / max-height — задаёт максимальные размеры окна.
  • width / height — задаёт фиксированные размеры.
  • fullscreen — делает окно на весь экран.
  • persistent — предотвращает закрытие при клике вне окна.
<v-dialog v-model="dialog" fullscreen persistent>
  <v-card>
    <v-card-title>Полноэкранный диалог</v-card-title>
    <v-card-text>
      Здесь можно разместить форму или галерею изображений.
    </v-card-text>
  </v-card>
</v-dialog>

persistent используется для обязательного взаимодействия с окном, например, при подтверждении важного действия.


Анимации и переходы

Vuetify автоматически применяет переходы и анимации при открытии и закрытии диалога.

  • transition — можно задать кастомный переход (dialog-transition, scale-transition, slide-y-transition и др.).
  • origin — точка, от которой начинается анимация (например, "top center").
<v-dialog v-model="dialog" transition="slide-y-transition" origin="top center">
  <v-card>
    <v-card-title>Диалог с анимацией</v-card-title>
  </v-card>
</v-dialog>

Использование origin создаёт эффект появления окна из конкретной точки, что делает интерфейс более плавным.


Диалог с формой

Диалоги часто используют для ввода данных. Важно правильно организовать валидацию и управление формой внутри v-dialog.

<v-dialog v-model="dialog" max-width="600">
  <v-card>
    <v-card-title>Форма регистрации</v-card-title>
    <v-card-text>
      <v-form ref="form" v-model="valid">
        <v-text-field label="Имя" v-model="name" :rules="[v => !!v || 'Введите имя']"></v-text-field>
        <v-text-field label="Email" v-model="email" :rules="[v => /.+@.+/.test(v) || 'Неверный email']"></v-text-field>
      </v-form>
    </v-card-text>
    <v-card-actions>
      <v-btn color="primary" text @click="submit">Отправить</v-btn>
      <v-btn text @click="dialog = false">Отмена</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>

Метод submit может проверять форму перед отправкой:

methods: {
  submit() {
    if (this.$refs.form.validate()) {
      // обработка данных формы
      this.dialog = false;
    }
  }
}

Вложенные и динамические диалоги

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

<v-dialog v-model="dialog1">
  <v-card>
    <v-card-title>Первый диалог</v-card-title>
    <v-card-actions>
      <v-btn text @click="dialog2 = true">Открыть второй</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>

<v-dialog v-model="dialog2">
  <v-card>
    <v-card-title>Второй диалог</v-card-title>
  </v-card>
</v-dialog>

Важно следить, чтобы каждое окно имело свой отдельный v-model, иначе могут возникнуть конфликты состояния.


Интеграция с другими компонентами Vuetify

v-dialog часто комбинируется с:

  • v-card — для структурированного контента;
  • v-form и v-text-field — для ввода данных;
  • v-btn — для действий пользователя;
  • v-date-picker, v-time-picker, v-select — для выбора данных внутри модального окна.
<v-dialog v-model="dialog" max-width="400">
  <v-card>
    <v-card-title>Выбор даты</v-card-title>
    <v-card-text>
      <v-date-picker v-model="date"></v-date-picker>
    </v-card-text>
    <v-card-actions>
      <v-btn text @click="dialog = false">Закрыть</v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>

Советы по производительности

  • Избегать большого количества одновременно открытых диалогов.
  • Использовать lazy для отложенной загрузки контента:
<v-dialog v-model="dialog" lazy>
  <!-- контент загружается только при открытии -->
</v-dialog>
  • Минимизировать сложные вычисления внутри v-card диалога, чтобы не замедлять рендеринг при открытии.

v-dialog в Vuetify — универсальный инструмент для модальных окон, поддерживающий гибкое управление, кастомные размеры, анимации и интеграцию с любыми компонентами интерфейса. Правильная настройка v-model, атрибутов размера и поведения при клике вне окна позволяет создавать качественный UX.