# Диалог
Модальный диалог. В Vue2 нет Teleport: узел всплывающего слоя монтируется в body на хуке mounted (позиционирование fixed), компонент сохраняет полную реактивную связь; закрытие контролируется кликом по маске, ESC, кнопкой закрытия или beforeClose; поддерживаются перетаскивание и блокировка прокрутки.
Диалог
<template>
<div class="demo-col">
<div class="demo-row" style="gap: 12px; flex-wrap: wrap">
<LhButton type="primary" @click="basic = true">Базовый диалог</LhButton>
<LhButton @click="center = true">position="center" по центру</LhButton>
<LhButton @click="bottom = true">position="bottom" внизу</LhButton>
<LhButton @click="full = true">fullscreen на весь экран</LhButton>
<LhButton @click="drag = true">draggable перетаскивание</LhButton>
<LhButton @click="strict = true">Закрытие по маске/Esc запрещено</LhButton>
<LhButton @click="guard = true">Перехват beforeClose</LhButton>
<LhButton @click="noClose = true">showClose=false</LhButton>
</div>
<LhDialog v-model="basic" title="Колофон" width="420px" :top="top" :z-index="2000">
<p style="margin: 0">Диалог монтируется в body; маска и содержимое имеют позиционирование fixed. top задаёт отступ сверху, zIndex — уровень наложения.</p>
<template #footer>
<LhButton @click="basic = false">Отмена</LhButton>
<LhButton type="primary" @click="basic = false">Подпись</LhButton>
</template>
</LhDialog>
<LhDialog v-model="center" title="Диалог по центру" position="center" width="360px" center>
<p style="margin: 0">position="center" центрирует по вертикали; center располагает заголовок и кнопки по центру.</p>
<template #footer>
<LhButton type="primary" @click="center = false">Понятно</LhButton>
</template>
</LhDialog>
<LhDialog v-model="bottom" title="Диалог внизу" position="bottom" width="480px">
<p style="margin: 0">position="bottom" отображается у нижнего края; подходит для панелей действий на мобильных.</p>
</LhDialog>
<LhDialog v-model="full" title="Полноэкранный просмотр" fullscreen>
<p style="margin: 0">fullscreen занимает всё окно просмотра; область содержимого подстраивается под оставшуюся высоту.</p>
<template #footer>
<LhButton type="primary" @click="full = false">Закрыть</LhButton>
</template>
</LhDialog>
<LhDialog v-model="drag" title="Перетащите за шапку" draggable width="420px">
<p style="margin: 0">При включённом draggable диалог можно перетаскивать, удерживая шапку.</p>
</LhDialog>
<LhDialog
v-model="strict"
title="Строгий режим"
width="400px"
:close-on-click-modal="false"
:close-on-press-escape="false"
:lock-scroll="true"
>
<p style="margin: 0">closeOnClickModal и closeOnPressEscape отключены, lockScroll блокирует прокрутку страницы — закрыть можно только кнопкой.</p>
<template #footer>
<LhButton type="primary" @click="strict = false">Только кнопкой</LhButton>
</template>
</LhDialog>
<LhDialog v-model="guard" title="Перехват перед закрытием" width="400px" :before-close="beforeClose">
<p style="margin: 0">beforeClose перехватывает закрытие: действительно закрывает только вызов done() (здесь демонстрируется повторное подтверждение).</p>
</LhDialog>
<LhDialog v-model="noClose" title="Без кнопки закрытия" width="360px" :show-close="false">
<p style="margin: 0">showClose=false скрывает кнопку закрытия в правом верхнем углу.</p>
<template #footer>
<LhButton type="primary" @click="noClose = false">Закрыть</LhButton>
</template>
</LhDialog>
</div>
</template>
<script>
export default {
data: () => ({
basic: false,
center: false,
bottom: false,
full: false,
drag: false,
strict: false,
guard: false,
noClose: false,
top: '15vh',
}),
methods: {
beforeClose(done) {
if (window.confirm('Закрыть диалог?')) done()
},
},
}
</script>
# Props
| Проп | Описание | Тип | По умолчанию |
|---|---|---|---|
| v-model | Видимость (model: modelValue/input; также поддерживается стандартный v-model, помимо :visible.sync) | boolean | false |
| title | Заголовок | string | '' |
| width | Ширина | string \| number | '480px' |
| position | Позиция | 'top' \| 'center' \| 'bottom' | 'center' |
| center | Центрирование заголовка и кнопок | boolean | false |
| fullscreen | Полноэкранный режим | boolean | false |
| showClose | Показывать кнопку закрытия | boolean | true |
| closeOnClickModal / closeOnPressEscape | Закрытие по маске / по ESC | boolean | true |
| draggable | Перетаскивание за шапку (с ограничением границей окна) | boolean | false |
| lockScroll | Блокировка прокрутки body | boolean | true |
| beforeClose | Перехват перед закрытием; действительное закрытие — вызов done() | (done) => void | — |
| top | Отступ сверху (действует при position=top) | string | '15vh' |
| zIndex / themeVars / bgPattern / sx | Уровень наложения и переопределение темы | — | — |
# Events
| Событие | Описание | Параметр колбэка |
|---|---|---|
| input | Синхронизация видимости v-model | boolean |
| open | Начало открытия (входной переход) | — |
| opened | Окончание открытия (переход завершён) | — |
| close | Начало закрытия (выходной переход) | — |
| closed | Окончание закрытия (переход завершён) | — |
# Slots
| Слот | Описание |
|---|---|
| default | Основной текст |
| header | Пользовательский заголовок |
| footer | Область действий внизу |
# Методы
| Метод | Описание |
|---|---|
| close() | Закрывает диалог |
| isVisible | Текущая видимость (defineExpose) |
Copyright © 2024-2026 FengMo WenXue