Modal
Универсальная панель-оверлей для форм, деталей и сложного контента. Поддерживает перетаскивание, полноэкранный режим, режим выдвижной панели, пользовательские переходы, вложенные модальные окна, ловушку фокуса, автозакрытие, программный API и многое другое.
<script setup>
const show = ref(false)
</script>
<template>
<button @click="show = true">Open Modal</button>
<VxModal v-model="show" title="Basic Modal">
<p>This is a basic modal.</p>
</VxModal>
</template>With Description
<template>
<VxModal v-model="show" title="Edit Profile" description="Make changes here." />
</template>Sizes
<template>
<VxModal size="sm" />
<VxModal size="md" />
<VxModal size="lg" />
<VxModal size="xl" />
<VxModal size="full" />
</template>Custom Width
Установите произвольную ширину с помощью свойства width.
<template>
<VxModal v-model="show" :width="666" title="Custom Width" />
<VxModal v-model="show" width="80%" title="Percentage Width" />
</template>Draggable
Перетаскивайте модальное окно за заголовок, чтобы изменить его положение.
<template>
<VxModal v-model="show" title="Drag Me" draggable />
</template>Fullscreen Toggle
Кнопка в заголовке позволяет пользователям разворачивать модальное окно на весь экран и обратно.
<template>
<VxModal v-model="show" title="Expand Me" fullscreenable />
</template>Before Close
Асинхронный обработчик, запускающийся перед закрытием. Верните false, чтобы предотвратить закрытие.
<script setup>
// Sync — native browser confirm
function beforeClose() {
return window.confirm('Discard changes?')
}
// Async — with useConfirm dialog
import { useConfirm } from 'veloxui'
const dialog = useConfirm()
async function beforeCloseAsync() {
// resolves = allow close, rejects = block close
await dialog.warning({
title: 'Discard Changes?',
confirmText: 'Discard',
cancelText: 'Keep Editing',
})
}
</script>
<template>
<VxModal v-model="show" :before-close="beforeClose" title="Guard" />
</template>Drawer Mode
Выезжает с любого края. Используйте свойство drawer со значениями left, right, top или bottom.
<template>
<VxModal v-model="show" drawer="left" title="Left" />
<VxModal v-model="show" drawer="right" title="Right" />
<VxModal v-model="show" drawer="top" title="Top" />
<VxModal v-model="show" drawer="bottom" title="Bottom" />
<VxModal v-model="show" drawer="right" size="lg" title="Wide Drawer" />
</template>Custom Transitions
Выберите анимацию: zoom (по умолчанию), fade, slide-up, slide-down, flip.
<template>
<VxModal transition="fade" />
<VxModal transition="slide-up" />
<VxModal transition="slide-down" />
<VxModal transition="flip" />
</template>Stacked Modals
Открывайте модальные окна поверх других. Каждое автоматически получает более высокий z-index.
<template>
<VxModal v-model="first" title="First">
<template #footer>
<button @click="second = true">Open Second</button>
</template>
</VxModal>
<VxModal v-model="second" title="Second" />
</template>Focus Trap
Включено по умолчанию. Клавиша Tab циклически перемещается внутри модального окна для обеспечения доступности.
<template>
<!-- Focus trap is enabled by default -->
<VxModal v-model="show" title="Focus Trap">
<input placeholder="Tab cycles here" />
</VxModal>
<!-- Disable it -->
<VxModal v-model="show" :focus-trap="false" />
</template>Auto Close
Автоматически закрывается через заданное время (мс).
<template>
<VxModal v-model="show" :auto-close="3000" title="Closes in 3s" />
</template>Destroy on Close
По умолчанию содержимое уничтожается при закрытии модального окна (destroy-on-close). Установите false, чтобы сохранить содержимое (сохраняет состояние формы, позицию прокрутки и т. д.).
<template>
<VxModal v-model="show" :destroy-on-close="false" title="Keep Alive" />
</template>Persistent
Нельзя закрыть кликом по оверлею или клавишей Escape. Показывает анимацию встряхивания.
<template>
<VxModal v-model="show" persistent title="Persistent" />
</template>Position
Размещайте модальное окно в любом углу или у любого края области просмотра.
<template>
<VxModal v-model="show" position="top-left" title="Top Left" />
<VxModal v-model="show" position="top-center" title="Top Center" />
<VxModal v-model="show" position="top-right" title="Top Right" />
<VxModal v-model="show" position="center" title="Center (default)" />
<VxModal v-model="show" position="bottom-left" title="Bottom Left" />
<VxModal v-model="show" position="bottom-center" title="Bottom Center" />
<VxModal v-model="show" position="bottom-right" title="Bottom Right" />
</template>Centered vs Top
<template>
<VxModal v-model="show" :centered="false" title="Top" />
</template>Hide Overlay
<template>
<VxModal v-model="show" hide-overlay />
</template>Loading
<template>
<VxModal v-model="show" loading title="Processing..." />
</template>Scrollable Content
<template>
<VxModal v-model="show" title="Terms" size="sm">
<div v-for="i in 20" :key="i"><p>Long content...</p></div>
</VxModal>
</template>Custom Header & Footer
<template>
<VxModal v-model="show">
<template #header>Custom header</template>
<template #footer>
<button @click="show = false">Cancel</button>
<button @click="show = false">Confirm</button>
</template>
</VxModal>
</template>Programmatic API
Используйте composable useModal(), чтобы открывать модальные окна из JavaScript без написания шаблонной разметки.
<script setup>
import { useModal } from 'veloxui'
const { open } = useModal()
function showModal() {
const instance = open({
title: 'Hello',
content: 'Created from JavaScript!',
size: 'sm',
})
// Close programmatically
// instance.close()
}
function showDrawer() {
open({
title: 'Drawer',
drawer: 'right',
content: 'A programmatic drawer.',
autoClose: 3000,
})
}
</script>Teleport Target
Монтирует модальное окно в пользовательский контейнер вместо body.
<template>
<VxModal v-model="show" teleport-to="#my-container" />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | false | Показать/скрыть (v-model) |
title | string | '' | Заголовок |
description | string | '' | Подзаголовок под заголовком |
size | 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'md' | Ширина модального окна |
width | string | number | — | Пользовательская ширина (переопределяет size) |
closable | boolean | true | Показывать кнопку закрытия |
closeOnOverlay | boolean | true | Закрывать при клике по оверлею |
closeOnEsc | boolean | true | Закрывать по нажатию Escape |
centered | boolean | true | Центрировать по вертикали |
persistent | boolean | false | Встряхивать вместо закрытия |
hideOverlay | boolean | false | Прозрачная подложка |
loading | boolean | false | Показывать оверлей загрузки |
draggable | boolean | false | Перетаскивание за заголовок |
fullscreenable | boolean | false | Показывать переключатель полноэкранного режима |
beforeClose | () => boolean | Promise<boolean> | — | Обработчик перед закрытием |
drawer | 'left' | 'right' | 'top' | 'bottom' | — | Режим выдвижной панели |
transition | 'zoom' | 'fade' | 'slide-up' | 'slide-down' | 'flip' | — | Анимация |
focusTrap | boolean | true | Удерживать Tab в пределах окна |
autoClose | number | 0 | Автозакрытие через мс |
destroyOnClose | boolean | true | Уничтожать содержимое при закрытии |
teleportTo | string | 'body' | Селектор цели для Teleport |
position | 'center' | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | 'center' | Положение модального окна |
Events
| Event | Description |
|---|---|
update:modelValue | Значение изменилось |
close | Закрытие вызвано |
opened | Переход открытия завершён |
closed | Переход закрытия завершён |
Slots
| Slot | Description |
|---|---|
default | Содержимое тела |
header | Пользовательский заголовок |
footer | Действия подвала (по умолчанию: кнопка закрытия) |
Exposed Methods
| Method | Description |
|---|---|
close() | Закрыть модальное окно программно |
toggleFullscreen() | Переключить полноэкранный режим |