Программное управление модалками

В библиотеке Naive UI модальные окна реализуются с помощью компонентов NModal, NDialog и вспомогательных API, таких как createDiscreteApi. Эти инструменты позволяют создавать как простые статические модалки, так и полностью динамические, управляемые программно.

Импорт и базовая структура

Для начала необходимо импортировать компоненты и API из библиотеки:

import { NButton, NModal } from 'naive-ui'
import { ref } from 'vue'

Основной способ управления видимостью модалки — это реактивная переменная ref. Например:

const showModal = ref(false)

В шаблоне:

<NButton @click="showModal = true">Открыть модалку</NButton>
<NModal v-model:show="showModal" title="Пример модалки">
  <p>Содержимое модального окна</p>
</NModal>

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


Использование createDiscreteApi для программного управления

Для более гибкого управления модалками и диалогами, Naive UI предоставляет createDiscreteApi. Этот метод позволяет создавать модалки динамически, без необходимости хранить их в шаблоне.

import { createDiscreteApi } from 'naive-ui'
const { dialog } = createDiscreteApi(['dialog'])

Программное открытие модалки:

dialog.info({
  title: 'Информационное окно',
  content: 'Это модальное окно создаётся программно',
  positiveText: 'Ок'
})

Параметры, доступные при создании модалки:

  • title – заголовок окна
  • content – основной контент
  • positiveText / negativeText – текст кнопок подтверждения и отмены
  • onPositiveClick / onNegativeClick – коллбэки при нажатии кнопок
  • maskClosable – возможность закрыть окно кликом по затемнению
  • closable – отображение крестика закрытия

Примечание: Динамическая модалка не требует заранее созданного шаблона и автоматически монтируется в DOM.


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

Помимо стандартного v-model:show, можно использовать события жизненного цикла модалки:

  • on-update:show — отслеживание изменений видимости
  • on-open — вызывается при открытии модалки
  • on-close — вызывается при закрытии модалки

Пример с логированием состояния:

<NModal
  v-model:show="showModal"
  title="Жизненный цикл модалки"
  @on-open="console.log('Модалка открыта')"
  @on-close="console.log('Модалка закрыта')"
>
  Контент окна
</NModal>

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


Динамическое управление списком модалок

Для проектов с множеством модальных окон часто требуется хранить их в массиве и управлять каждой индивидуально. Это реализуется через массив объектов состояния:

const modals = ref([])

function openModal(id, title, content) {
  modals.value.push({ id, title, content, show: true })
}

function closeModal(id) {
  const index = modals.value.findIndex(m => m.id === id)
  if (index !== -1) modals.value.splice(index, 1)
}

В шаблоне:

<NModal
  v-for="modal in modals"
  :key="modal.id"
  v-model:show="modal.show"
  :title="modal.title"
  @on-close="closeModal(modal.id)"
>
  {{ modal.content }}
</NModal>

Преимущество: каждый объект модалки имеет собственное состояние, что облегчает управление сложными интерфейсами с множеством диалогов.


Интеграция с формами и подтверждениями

Модалки часто используются для подтверждения действий или заполнения форм. Для этого Naive UI позволяет вставлять любые компоненты внутрь NModal:

<NModal v-model:show="showFormModal" title="Форма">
  <n-form :model="formModel">
    <n-form-item label="Имя">
      <n-input v-model:value="formModel.name" />
    </n-form-item>
    <n-form-item label="Email">
      <n-input v-model:value="formModel.email" />
    </n-form-item>
  </n-form>
  <template #footer>
    <NButton @click="submitForm">Отправить</NButton>
    <NButton @click="showFormModal = false">Отмена</NButton>
  </template>
</NModal>

Особенности:

  • Можно использовать слот footer для кастомизации кнопок
  • Доступ к методам формы через реактивные переменные или refs
  • Любые интерактивные компоненты внутри модалки полностью работают с реактивностью Vue

Переиспользуемые модалки

Для больших проектов рекомендуется создавать компоненты-модалки, которые можно вызывать программно:

export default {
  props: ['show', 'title', 'content'],
  emits: ['update:show'],
  setup(props, { emit }) {
    const close = () => emit('update:show', false)
    return { close }
  },
  template: `
    <NModal v-model:show="show" :title="title">
      <p>{{ content }}</p>
      <template #footer>
        <NButton @click="close">Закрыть</NButton>
      </template>
    </NModal>
  `
}

Такой компонент легко интегрируется с createDiscreteApi или напрямую в шаблоне, обеспечивая единый интерфейс управления модальными окнами во всем приложении.


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

  • Не держать все модалки постоянно в DOM — лучше монтировать их динамически
  • Использовать lazy-loading для сложных форм внутри модалки
  • Для часто используемых подтверждений применять createDiscreteApi, чтобы избежать лишнего рендера компонентов

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