Skip to content
API 风格:

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 ​

PropDescripciónTipoPredeterminado
modelValueSi se muestra el diálogobooleanfalse
titleTítulo del diálogostring''
widthAnchura del diálogostring | number'480px'
fullscreenSi es a pantalla completabooleanfalse
showCloseSi se muestra el botón de cierrebooleantrue
closeOnClickModalSi se cierra al hacer clic en la máscarabooleantrue
closeOnPressEscapeSi se cierra al pulsar ESCbooleantrue
draggableSi se puede arrastrarbooleanfalse
centerSi se muestra centrado (mantenido por compatibilidad; se recomienda position)booleanfalse
positionPosición del diálogo: top / center / bottom"top" | "center" | "bottom"'center'
lockScrollSi se bloquea el desplazamientobooleantrue
beforeCloseRetrollamada antes de cerrar(done: () => void) => void—
topDistancia desde la parte superior (px)string'15vh'
zIndexz-indexnumber—
themeVarsVariables de tema a nivel de componente; sobrescribe la configuración del ConfigProvider{ [x: string]: string; }—
bgPatternPatrón de fondo a nivel de componente; sobrescribe la configuración del ConfigProviderstring—
sxProps de disposición rápidaLhSxProps—

Events ​

EventoDescripciónParámetros de la retrollamada
update:modelValueCambia el estado de visibilidad(value: boolean)
openTermina la animación de apertura—
closeTermina la animación de cierre—
openedSe dispara cuando el diálogo está completamente abierto—
closedSe dispara cuando el diálogo está completamente cerrado—

Slots ​

SlotDescripción
defaultContenido del diálogo
headerZona del título del diálogo
footerZona 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
}

La belleza de la tradición, el cimiento del código