Диалог
Модальный диалог для отображения важной информации или подтверждения действий.
Базовое использование
Базовое использование
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible1 = ref(false)
</script>
<template>
<!-- Базовое использование -->
<LhButton @click="dialogVisible1 = true">Открыть диалог</LhButton>
<LhDialog v-model="dialogVisible1" title="Подсказка">
<p>Это содержимое диалога</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">Отмена</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">ОК</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible1: false
}
}
}
</script>
<template>
<!-- Базовое использование -->
<LhButton @click="dialogVisible1 = true">Открыть диалог</LhButton>
<LhDialog v-model="dialogVisible1" title="Подсказка">
<p>Это содержимое диалога</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">Отмена</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">ОК</LhButton>
</template>
</LhDialog>
</template>Пользовательские ширина и высота
Пользовательская ширина
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible2 = ref(false)
</script>
<template>
<!-- Пользовательские ширина и высота -->
<LhButton @click="dialogVisible2 = true">Открыть большой диалог</LhButton>
<LhDialog v-model="dialogVisible2" title="Большой диалог" width="600px">
<p>Диалог пользовательского размера</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">Закрыть</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible2: false
}
}
}
</script>
<template>
<!-- Пользовательские ширина и высота -->
<LhButton @click="dialogVisible2 = true">Открыть большой диалог</LhButton>
<LhDialog v-model="dialogVisible2" title="Большой диалог" width="600px">
<p>Диалог пользовательского размера</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">Закрыть</LhButton>
</template>
</LhDialog>
</template>Перетаскивание
Перетаскивание
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible3 = ref(false)
</script>
<template>
<!-- Перетаскивание -->
<LhButton @click="dialogVisible3 = true">Открыть перетаскиваемый диалог</LhButton>
<LhDialog v-model="dialogVisible3" title="Перетаскиваемый диалог" draggable>
<p>Потяните за заголовок, чтобы переместить этот диалог.</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">Закрыть</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible3: false
}
}
}
</script>
<template>
<!-- Перетаскивание -->
<LhButton @click="dialogVisible3 = true">Открыть перетаскиваемый диалог</LhButton>
<LhDialog v-model="dialogVisible3" title="Перетаскиваемый диалог" draggable>
<p>Потяните за заголовок, чтобы переместить этот диалог.</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">Закрыть</LhButton>
</template>
</LhDialog>
</template>Пользовательская тема
Применение к диалогу пользовательской цветовой темы.
Диалог в теме 青花瓷 (сине-белый фарфор)
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhConfigProvider, LhButton, LhDialog } from '@lh-ui/vue3'
const dialogThemeVisible = ref(false)
const cerblueTheme = {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
}
</script>
<template>
<LhConfigProvider :theme-vars="cerblueTheme">
<!-- Тема сине-белого фарфора -->
<LhButton @click="dialogThemeVisible = true" type="primary">Открыть тематический диалог</LhButton>
<LhDialog v-model="dialogThemeVisible" title="Тема сине-белого фарфора">
<p>В этом диалоге используется тема сине-белого фарфора</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">Закрыть</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhConfigProvider, LhButton, LhDialog },
data() {
return {
dialogThemeVisible: false,
cerblueTheme: {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
},
}
},
}
</script>
<template>
<LhConfigProvider :theme-vars="cerblueTheme">
<!-- Тема сине-белого фарфора -->
<LhButton @click="dialogThemeVisible = true" type="primary">Открыть тематический диалог</LhButton>
<LhDialog v-model="dialogThemeVisible" title="Тема сине-белого фарфора">
<p>В этом диалоге используется тема сине-белого фарфора</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">Закрыть</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>Подробнее о темах см. Кастомизация темы.
Быстрая компоновка sx
С помощью свойства sx можно быстро задать размеры и отступы Dialog.
Быстрая компоновка sx
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const visible = ref(false)
</script>
<template>
<!-- Открыть диалог -->
<LhButton @click="visible = true">Открыть диалог</LhButton>
<!-- Диалог с компоновкой sx -->
<LhDialog v-model="visible" title="Компоновка sx" :sx="{ maxWidth: 400 }">
<p>Задана максимальная ширина</p>
<template #footer>
<LhButton @click="visible = false">Отмена</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return { visible: false }
},
}
</script>
<template>
<!-- Открыть диалог -->
<LhButton @click="visible = true">Открыть диалог</LhButton>
<!-- Диалог с компоновкой sx -->
<LhDialog v-model="visible" title="Компоновка sx" :sx="{ maxWidth: 400 }">
<p>Задана максимальная ширина</p>
<template #footer>
<LhButton @click="visible = false">Отмена</LhButton>
</template>
</LhDialog>
</template>Интернационализация
Тексты диалога можно переключать через LhConfigProvider в сочетании с языковыми пакетами.
Интернационализация
vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { LhConfigProvider, LhButton, LhDialog, zhCN, enUS } from '@lh-ui/vue3'
const locale = ref('zh-CN')
const i18nVisible = ref(false)
const messages = computed(() => (locale.value === 'zh-CN' ? zhCN : enUS))
</script>
<template>
<LhConfigProvider :locale="messages">
<!-- Открыть диалог -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- Диалог с интернационализацией -->
<LhDialog v-model="i18nVisible" :title="locale === 'zh-CN' ? '提示' : 'Notice'">
<p>{{ locale === 'zh-CN' ? '对话框内容' : 'Dialog content' }}</p>
<template #footer>
<LhButton @click="i18nVisible = false">
{{ locale === 'zh-CN' ? '取消' : 'Cancel' }}
</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhButton, LhDialog, zhCN, enUS } from '@lh-ui/vue3'
export default {
components: { LhConfigProvider, LhButton, LhDialog },
data() {
return {
locale: 'zh-CN',
i18nVisible: false,
}
},
computed: {
messages() {
return this.locale === 'zh-CN' ? zhCN : enUS
},
},
}
</script>
<template>
<LhConfigProvider :locale="messages">
<!-- Открыть диалог -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- Диалог с интернационализацией -->
<LhDialog v-model="i18nVisible" :title="locale === 'zh-CN' ? '提示' : 'Notice'">
<p>{{ locale === 'zh-CN' ? '对话框内容' : 'Dialog content' }}</p>
<template #footer>
<LhButton @click="i18nVisible = false">
{{ locale === 'zh-CN' ? '取消' : 'Cancel' }}
</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>Поведенческие переключатели
Способ закрытия / блокировка прокрутки / beforeClose
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogAdv1 = ref(false)
const dialogAdv2 = ref(false)
const dialogAdv3 = ref(false)
function handleAdvBeforeClose(done: () => void) {
setTimeout(done, 500)
}
</script>
<template>
<!-- Только кнопка закрытия -->
<LhButton @click="dialogAdv1 = true">Только кнопка закрытия</LhButton>
<LhDialog
v-model="dialogAdv1"
title="Только кнопка закрытия"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>Кнопка закрытия в правом верхнем углу скрыта; нажатие на маску и ESC также не закрывают диалог — только нижняя кнопка.</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">Понятно</LhButton>
</template>
</LhDialog>
<!-- Без блокировки прокрутки -->
<LhButton @click="dialogAdv2 = true">Без блокировки прокрутки</LhButton>
<LhDialog v-model="dialogAdv2" title="Без блокировки прокрутки" :lock-scroll="false">
<p>При открытом диалоге страницу по-прежнему можно прокручивать — подходит для коротких лёгких подсказок.</p>
</LhDialog>
<!-- Асинхронное закрытие -->
<LhButton @click="dialogAdv3 = true">Асинхронное закрытие</LhButton>
<LhDialog v-model="dialogAdv3" title="Асинхронное закрытие" :before-close="handleAdvBeforeClose">
<p>После нажатия кнопки закрытия, маски или ESC закрытие происходит с задержкой 500 мс (имитация проверки перед закрытием).</p>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogAdv1: false,
dialogAdv2: false,
dialogAdv3: false,
}
},
methods: {
handleAdvBeforeClose(done) {
setTimeout(done, 500)
},
},
}
</script>
<template>
<!-- Только кнопка закрытия -->
<LhButton @click="dialogAdv1 = true">Только кнопка закрытия</LhButton>
<LhDialog
v-model="dialogAdv1"
title="Только кнопка закрытия"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>Кнопка закрытия в правом верхнем углу скрыта; нажатие на маску и ESC также не закрывают диалог — только нижняя кнопка.</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">Понятно</LhButton>
</template>
</LhDialog>
<!-- Без блокировки прокрутки -->
<LhButton @click="dialogAdv2 = true">Без блокировки прокрутки</LhButton>
<LhDialog v-model="dialogAdv2" title="Без блокировки прокрутки" :lock-scroll="false">
<p>При открытом диалоге страницу по-прежнему можно прокручивать — подходит для коротких лёгких подсказок.</p>
</LhDialog>
<!-- Асинхронное закрытие -->
<LhButton @click="dialogAdv3 = true">Асинхронное закрытие</LhButton>
<LhDialog v-model="dialogAdv3" title="Асинхронное закрытие" :before-close="handleAdvBeforeClose">
<p>После нажатия кнопки закрытия, маски или ESC закрытие происходит с задержкой 500 мс (имитация проверки перед закрытием).</p>
</LhDialog>
</template>Позиция и слой
fullscreen / position / top / zIndex / center
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogAdv4 = ref(false)
const dialogAdv5 = ref(false)
const dialogAdv6 = ref(false)
const dialogAdv7 = ref(false)
</script>
<template>
<!-- Полный экран -->
<LhButton @click="dialogAdv4 = true">Полный экран</LhButton>
<LhDialog v-model="dialogAdv4" title="Полноэкранный диалог" fullscreen>
<p>При fullscreen диалог занимает всю область просмотра.</p>
</LhDialog>
<!-- Нижняя позиция -->
<LhButton @click="dialogAdv5 = true">Нижняя позиция</LhButton>
<LhDialog v-model="dialogAdv5" title="Нижняя позиция" position="bottom">
<p>При position="bottom" диалог отображается у нижнего края области просмотра.</p>
</LhDialog>
<!-- Сверху + слой -->
<LhButton @click="dialogAdv6 = true">Сверху + слой</LhButton>
<LhDialog v-model="dialogAdv6" title="Сверху + слой" position="top" top="10vh" :z-index="3000">
<p>top задаёт расстояние от верхнего края области просмотра, z-index управляет порядком наложения.</p>
</LhDialog>
<!-- Контент по центру -->
<LhButton @click="dialogAdv7 = true">Контент по центру (center)</LhButton>
<LhDialog v-model="dialogAdv7" title="Контент по центру" center>
<p>center центрирует заголовок и содержимое (для совместимости со старыми версиями; в новом коде рекомендуется использовать position).</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">Отмена</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">ОК</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogAdv4: false,
dialogAdv5: false,
dialogAdv6: false,
dialogAdv7: false,
}
},
}
</script>
<template>
<!-- Полный экран -->
<LhButton @click="dialogAdv4 = true">Полный экран</LhButton>
<LhDialog v-model="dialogAdv4" title="Полноэкранный диалог" fullscreen>
<p>При fullscreen диалог занимает всю область просмотра.</p>
</LhDialog>
<!-- Нижняя позиция -->
<LhButton @click="dialogAdv5 = true">Нижняя позиция</LhButton>
<LhDialog v-model="dialogAdv5" title="Нижняя позиция" position="bottom">
<p>При position="bottom" диалог отображается у нижнего края области просмотра.</p>
</LhDialog>
<!-- Сверху + слой -->
<LhButton @click="dialogAdv6 = true">Сверху + слой</LhButton>
<LhDialog v-model="dialogAdv6" title="Сверху + слой" position="top" top="10vh" :z-index="3000">
<p>top задаёт расстояние от верхнего края области просмотра, z-index управляет порядком наложения.</p>
</LhDialog>
<!-- Контент по центру -->
<LhButton @click="dialogAdv7 = true">Контент по центру (center)</LhButton>
<LhDialog v-model="dialogAdv7" title="Контент по центру" center>
<p>center центрирует заголовок и содержимое (для совместимости со старыми версиями; в новом коде рекомендуется использовать position).</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">Отмена</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">ОК</LhButton>
</template>
</LhDialog>
</template>Dialog API
Props
| Свойство | Описание | Тип | По умолчанию |
|---|---|---|---|
| modelValue | Показывать ли диалог | boolean | false |
| title | Заголовок диалога | string | '' |
| width | Ширина диалога | string | number | '480px' |
| fullscreen | На весь экран | boolean | false |
| showClose | Показывать ли кнопку закрытия | boolean | true |
| closeOnClickModal | Закрывать ли при нажатии на маску | boolean | true |
| closeOnPressEscape | Закрывать ли при нажатии ESC | boolean | true |
| draggable | Можно ли перетаскивать | boolean | false |
| center | Центрировать ли отображение (для совместимости со старыми версиями, рекомендуется использовать position) | boolean | false |
| position | Позиция диалога: top / center / bottom | "top" | "center" | "bottom" | 'center' |
| lockScroll | Блокировать ли прокрутку | boolean | true |
| beforeClose | Колбэк перед закрытием | (done: () => void) => void | — |
| top | Отступ сверху (px) | string | '15vh' |
| zIndex | z-index | number | — |
| themeVars | Тематические переменные уровня компонента, переопределяют конфигурацию ConfigProvider | { [x: string]: string; } | — |
| bgPattern | Фоновый узор уровня компонента, переопределяет конфигурацию ConfigProvider | string | — |
| sx | Свойство быстрой компоновки sx | LhSxProps | — |
Events
| Событие | Описание | Параметр обратного вызова |
|---|---|---|
| update:modelValue | Изменение состояния отображения | (value: boolean) |
| open | Окончание анимации открытия | — |
| close | Окончание анимации закрытия | — |
| opened | Срабатывает после полного открытия диалога | — |
| closed | Срабатывает после полного закрытия диалога | — |
Slots
| Слот | Описание |
|---|---|
| default | Содержимое диалога |
| header | Область заголовка диалога |
| footer | Область внизу диалога |
Типы
Структура открытых TypeScript-типов этого компонента (автоматически извлечено из packages/components/dialog/src/types.ts и исходников @lh-ui/share/core/*; раскройте каждый пункт, чтобы увидеть полное определение; описания свойств — в таблице Props выше):
LhDialogProps
ts
/**
* Props компонента Dialog
*/
export interface LhDialogProps {
/** Показывать ли */
modelValue?: boolean
/** Заголовок */
title?: string
/** Ширина */
width?: string | number
/** На весь экран */
fullscreen?: boolean
/** Показывать ли кнопку закрытия */
showClose?: boolean
/** Закрывать ли при нажатии на маску */
closeOnClickModal?: boolean
/** Закрывать ли при нажатии ESC */
closeOnPressEscape?: boolean
/** Можно ли перетаскивать */
draggable?: boolean
/** Центрировать ли отображение (для совместимости со старыми версиями, рекомендуется использовать position) */
center?: boolean
/** Позиция диалога: top / center / bottom */
position?: 'top' | 'center' | 'bottom'
/** Блокировать ли прокрутку */
lockScroll?: boolean
/** Колбэк перед закрытием */
beforeClose?: (done: () => void) => void
/** Отступ сверху (px) */
top?: string
/** z-index */
zIndex?: number
/** Тематические переменные уровня компонента, переопределяют конфигурацию ConfigProvider */
themeVars?: Record<string, string>
/** Фоновый узор уровня компонента, переопределяет конфигурацию ConfigProvider */
bgPattern?: string
/** Свойство быстрой компоновки sx */
sx?: LhSxProps
}