Skip to content
API 风格:

Диалог ​

Модальный диалог для отображения важной информации или подтверждения действий.

Базовое использование ​

Базовое использование
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Показывать ли диалогbooleanfalse
titleЗаголовок диалогаstring''
widthШирина диалогаstring | number'480px'
fullscreenНа весь экранbooleanfalse
showCloseПоказывать ли кнопку закрытияbooleantrue
closeOnClickModalЗакрывать ли при нажатии на маскуbooleantrue
closeOnPressEscapeЗакрывать ли при нажатии ESCbooleantrue
draggableМожно ли перетаскиватьbooleanfalse
centerЦентрировать ли отображение (для совместимости со старыми версиями, рекомендуется использовать position)booleanfalse
positionПозиция диалога: top / center / bottom"top" | "center" | "bottom"'center'
lockScrollБлокировать ли прокруткуbooleantrue
beforeCloseКолбэк перед закрытием(done: () => void) => void—
topОтступ сверху (px)string'15vh'
zIndexz-indexnumber—
themeVarsТематические переменные уровня компонента, переопределяют конфигурацию ConfigProvider{ [x: string]: string; }—
bgPatternФоновый узор уровня компонента, переопределяет конфигурацию ConfigProviderstring—
sxСвойство быстрой компоновки sxLhSxProps—

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
}

Красота традиций — основа кода