Diálogo
Componente de diálogo modal, utilizado para mostrar información importante o confirmar acciones.
Uso básico
Uso básico
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible1 = ref(false)
</script>
<template>
<!-- Uso básico -->
<LhButton @click="dialogVisible1 = true">Abrir diálogo</LhButton>
<LhDialog v-model="dialogVisible1" title="Aviso">
<p>Este es el contenido del diálogo</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">Cancelar</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">Aceptar</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible1: false
}
}
}
</script>
<template>
<!-- Uso básico -->
<LhButton @click="dialogVisible1 = true">Abrir diálogo</LhButton>
<LhDialog v-model="dialogVisible1" title="Aviso">
<p>Este es el contenido del diálogo</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">Cancelar</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">Aceptar</LhButton>
</template>
</LhDialog>
</template>Anchura y altura personalizadas
Anchura personalizada
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible2 = ref(false)
</script>
<template>
<!-- Anchura y altura personalizadas -->
<LhButton @click="dialogVisible2 = true">Abrir diálogo grande</LhButton>
<LhDialog v-model="dialogVisible2" title="Diálogo grande" width="600px">
<p>Un diálogo con tamaño personalizado</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">Cerrar</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible2: false
}
}
}
</script>
<template>
<!-- Anchura y altura personalizadas -->
<LhButton @click="dialogVisible2 = true">Abrir diálogo grande</LhButton>
<LhDialog v-model="dialogVisible2" title="Diálogo grande" width="600px">
<p>Un diálogo con tamaño personalizado</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">Cerrar</LhButton>
</template>
</LhDialog>
</template>Arrastrable
Arrastrable
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible3 = ref(false)
</script>
<template>
<!-- Arrastrable -->
<LhButton @click="dialogVisible3 = true">Abrir diálogo arrastrable</LhButton>
<LhDialog v-model="dialogVisible3" title="Diálogo arrastrable" draggable>
<p>Arrastrando la barra de título se puede mover este diálogo.</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">Cerrar</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible3: false
}
}
}
</script>
<template>
<!-- Arrastrable -->
<LhButton @click="dialogVisible3 = true">Abrir diálogo arrastrable</LhButton>
<LhDialog v-model="dialogVisible3" title="Diálogo arrastrable" draggable>
<p>Arrastrando la barra de título se puede mover este diálogo.</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">Cerrar</LhButton>
</template>
</LhDialog>
</template>Tema personalizado
Aplica al diálogo una paleta temática personalizada.
Diálogo con tema porcelana azul y blanco
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">
<!-- Tema porcelana azul y blanco -->
<LhButton @click="dialogThemeVisible = true" type="primary">Abrir diálogo con tema</LhButton>
<LhDialog v-model="dialogThemeVisible" title="Tema porcelana azul y blanco">
<p>Este diálogo usa la paleta del tema porcelana azul y blanco</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">Cerrar</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">
<!-- Tema porcelana azul y blanco -->
<LhButton @click="dialogThemeVisible = true" type="primary">Abrir diálogo con tema</LhButton>
<LhDialog v-model="dialogThemeVisible" title="Tema porcelana azul y blanco">
<p>Este diálogo usa la paleta del tema porcelana azul y blanco</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">Cerrar</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>Para más temas, consulta Personalización del tema.
Disposición rápida con sx
Con la prop sx puedes establecer rápidamente dimensiones y márgenes del Dialog.
Disposición rápida con sx
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const visible = ref(false)
</script>
<template>
<!-- Abrir diálogo -->
<LhButton @click="visible = true">Abrir diálogo</LhButton>
<!-- Diálogo con disposición sx -->
<LhDialog v-model="visible" title="Disposición sx" :sx="{ maxWidth: 400 }">
<p>Se ha definido una anchura máxima</p>
<template #footer>
<LhButton @click="visible = false">Cancelar</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return { visible: false }
},
}
</script>
<template>
<!-- Abrir diálogo -->
<LhButton @click="visible = true">Abrir diálogo</LhButton>
<!-- Diálogo con disposición sx -->
<LhDialog v-model="visible" title="Disposición sx" :sx="{ maxWidth: 400 }">
<p>Se ha definido una anchura máxima</p>
<template #footer>
<LhButton @click="visible = false">Cancelar</LhButton>
</template>
</LhDialog>
</template>Internacionalización
El texto del diálogo puede internacionalizarse con LhConfigProvider y un paquete de idioma.
Internacionalización
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">
<!-- Abrir diálogo -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- Diálogo internacionalizado -->
<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">
<!-- Abrir diálogo -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- Diálogo internacionalizado -->
<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>Interruptores de comportamiento
Forma de cerrarlo / bloqueo del desplazamiento / 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>
<!-- Cerrar solo con el botón -->
<LhButton @click="dialogAdv1 = true">Cerrar solo con el botón</LhButton>
<LhDialog
v-model="dialogAdv1"
title="Cerrar solo con el botón"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>Se oculta el botón de cierre de la esquina superior derecha; hacer clic en la máscara o pulsar ESC tampoco lo cierra: solo puede cerrarse con los botones inferiores.</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">Entendido</LhButton>
</template>
</LhDialog>
<!-- Sin bloqueo del desplazamiento -->
<LhButton @click="dialogAdv2 = true">Sin bloqueo del desplazamiento</LhButton>
<LhDialog v-model="dialogAdv2" title="Sin bloqueo del desplazamiento" :lock-scroll="false">
<p>Con el diálogo abierto, la página sigue pudiéndose desplazar; es adecuado para avisos ligeros de contenido corto.</p>
</LhDialog>
<!-- Cierre asíncrono -->
<LhButton @click="dialogAdv3 = true">Cierre asíncrono</LhButton>
<LhDialog v-model="dialogAdv3" title="Cierre asíncrono" :before-close="handleAdvBeforeClose">
<p>Tras hacer clic en el botón de cierre, en la máscara o pulsar ESC, el cierre real se retrasa 500 ms (simula una validación previa al cierre).</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>
<!-- Cerrar solo con el botón -->
<LhButton @click="dialogAdv1 = true">Cerrar solo con el botón</LhButton>
<LhDialog
v-model="dialogAdv1"
title="Cerrar solo con el botón"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>Se oculta el botón de cierre de la esquina superior derecha; hacer clic en la máscara o pulsar ESC tampoco lo cierra: solo puede cerrarse con los botones inferiores.</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">Entendido</LhButton>
</template>
</LhDialog>
<!-- Sin bloqueo del desplazamiento -->
<LhButton @click="dialogAdv2 = true">Sin bloqueo del desplazamiento</LhButton>
<LhDialog v-model="dialogAdv2" title="Sin bloqueo del desplazamiento" :lock-scroll="false">
<p>Con el diálogo abierto, la página sigue pudiéndose desplazar; es adecuado para avisos ligeros de contenido corto.</p>
</LhDialog>
<!-- Cierre asíncrono -->
<LhButton @click="dialogAdv3 = true">Cierre asíncrono</LhButton>
<LhDialog v-model="dialogAdv3" title="Cierre asíncrono" :before-close="handleAdvBeforeClose">
<p>Tras hacer clic en el botón de cierre, en la máscara o pulsar ESC, el cierre real se retrasa 500 ms (simula una validación previa al cierre).</p>
</LhDialog>
</template>Posición y jerarquía
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>
<!-- Pantalla completa -->
<LhButton @click="dialogAdv4 = true">Pantalla completa</LhButton>
<LhDialog v-model="dialogAdv4" title="Diálogo a pantalla completa" fullscreen>
<p>Con fullscreen, el diálogo ocupa todo el viewport.</p>
</LhDialog>
<!-- Posición inferior -->
<LhButton @click="dialogAdv5 = true">Posición inferior</LhButton>
<LhDialog v-model="dialogAdv5" title="Posición inferior" position="bottom">
<p>Con position="bottom", el diálogo se muestra junto al borde inferior del viewport.</p>
</LhDialog>
<!-- Desplazamiento superior + jerarquía -->
<LhButton @click="dialogAdv6 = true">Desplazamiento superior + jerarquía</LhButton>
<LhDialog v-model="dialogAdv6" title="Desplazamiento superior + jerarquía" position="top" top="10vh" :z-index="3000">
<p>top ajusta la distancia respecto al borde superior del viewport; z-index controla el orden de apilamiento.</p>
</LhDialog>
<!-- Contenido centrado -->
<LhButton @click="dialogAdv7 = true">Contenido centrado (center)</LhButton>
<LhDialog v-model="dialogAdv7" title="Contenido centrado" center>
<p>center centra el título y el contenido (mantenido por compatibilidad; en código nuevo se recomienda position).</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">Cancelar</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">Aceptar</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>
<!-- Pantalla completa -->
<LhButton @click="dialogAdv4 = true">Pantalla completa</LhButton>
<LhDialog v-model="dialogAdv4" title="Diálogo a pantalla completa" fullscreen>
<p>Con fullscreen, el diálogo ocupa todo el viewport.</p>
</LhDialog>
<!-- Posición inferior -->
<LhButton @click="dialogAdv5 = true">Posición inferior</LhButton>
<LhDialog v-model="dialogAdv5" title="Posición inferior" position="bottom">
<p>Con position="bottom", el diálogo se muestra junto al borde inferior del viewport.</p>
</LhDialog>
<!-- Desplazamiento superior + jerarquía -->
<LhButton @click="dialogAdv6 = true">Desplazamiento superior + jerarquía</LhButton>
<LhDialog v-model="dialogAdv6" title="Desplazamiento superior + jerarquía" position="top" top="10vh" :z-index="3000">
<p>top ajusta la distancia respecto al borde superior del viewport; z-index controla el orden de apilamiento.</p>
</LhDialog>
<!-- Contenido centrado -->
<LhButton @click="dialogAdv7 = true">Contenido centrado (center)</LhButton>
<LhDialog v-model="dialogAdv7" title="Contenido centrado" center>
<p>center centra el título y el contenido (mantenido por compatibilidad; en código nuevo se recomienda position).</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">Cancelar</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">Aceptar</LhButton>
</template>
</LhDialog>
</template>Dialog API
Props
| Prop | Descripción | Tipo | Predeterminado |
|---|---|---|---|
| modelValue | Si se muestra el diálogo | boolean | false |
| title | Título del diálogo | string | '' |
| width | Anchura del diálogo | string | number | '480px' |
| fullscreen | Si es a pantalla completa | boolean | false |
| showClose | Si se muestra el botón de cierre | boolean | true |
| closeOnClickModal | Si se cierra al hacer clic en la máscara | boolean | true |
| closeOnPressEscape | Si se cierra al pulsar ESC | boolean | true |
| draggable | Si se puede arrastrar | boolean | false |
| center | Si se muestra centrado (mantenido por compatibilidad; se recomienda position) | boolean | false |
| position | Posición del diálogo: top / center / bottom | "top" | "center" | "bottom" | 'center' |
| lockScroll | Si se bloquea el desplazamiento | boolean | true |
| beforeClose | Retrollamada antes de cerrar | (done: () => void) => void | — |
| top | Distancia desde la parte superior (px) | string | '15vh' |
| zIndex | z-index | number | — |
| themeVars | Variables de tema a nivel de componente; sobrescribe la configuración del ConfigProvider | { [x: string]: string; } | — |
| bgPattern | Patrón de fondo a nivel de componente; sobrescribe la configuración del ConfigProvider | string | — |
| sx | Props de disposición rápida | LhSxProps | — |
Events
| Evento | Descripción | Parámetros de la retrollamada |
|---|---|---|
| update:modelValue | Cambia el estado de visibilidad | (value: boolean) |
| open | Termina la animación de apertura | — |
| close | Termina la animación de cierre | — |
| opened | Se dispara cuando el diálogo está completamente abierto | — |
| closed | Se dispara cuando el diálogo está completamente cerrado | — |
Slots
| Slot | Descripción |
|---|---|
| default | Contenido del diálogo |
| header | Zona del título del diálogo |
| footer | Zona inferior del diálogo |
Definiciones de tipos
Las estructuras de tipos TypeScript exportadas por este componente (extraídas automáticamente de packages/components/dialog/src/types.ts y de las fuentes @lh-ui/share/core/*; abre cada entrada para ver la definición completa; la descripción de los atributos está en la tabla de Props de arriba):
LhDialogProps
ts
/**
* Props del componente Dialog
*/
export interface LhDialogProps {
/** Si se muestra */
modelValue?: boolean
/** Título */
title?: string
/** Anchura */
width?: string | number
/** Si es a pantalla completa */
fullscreen?: boolean
/** Si se muestra el botón de cierre */
showClose?: boolean
/** Si se cierra al hacer clic en la máscara */
closeOnClickModal?: boolean
/** Si se cierra al pulsar ESC */
closeOnPressEscape?: boolean
/** Si se puede arrastrar */
draggable?: boolean
/** Si se muestra centrado (mantenido por compatibilidad; se recomienda position) */
center?: boolean
/** Posición del diálogo: top / center / bottom */
position?: 'top' | 'center' | 'bottom'
/** Si se bloquea el desplazamiento */
lockScroll?: boolean
/** Retrollamada antes de cerrar */
beforeClose?: (done: () => void) => void
/** Distancia desde la parte superior (px) */
top?: string
/** z-index */
zIndex?: number
/** Variables de tema a nivel de componente; sobrescribe la configuración del ConfigProvider */
themeVars?: Record<string, string>
/** Patrón de fondo a nivel de componente; sobrescribe la configuración del ConfigProvider */
bgPattern?: string
/** Props de disposición rápida */
sx?: LhSxProps
}