# Diálogo

Diálogo modal. Vue2 no dispone de Teleport: el anfitrión de la capa emergente se monta en el body durante mounted (con posicionamiento fixed) y el componente conserva la conexión reactiva completa. El cierre se puede controlar mediante la máscara, ESC, el botón de cierre o beforeClose; admite arrastrar y el bloqueo del desplazamiento.

Diálogo
<template>
  <div class="demo-col">
    <div class="demo-row" style="gap: 12px; flex-wrap: wrap">
      <LhButton type="primary" @click="basic = true">Diálogo básico</LhButton>
      <LhButton @click="center = true">position="center" centrado</LhButton>
      <LhButton @click="bottom = true">position="bottom" abajo</LhButton>
      <LhButton @click="full = true">fullscreen a pantalla completa</LhButton>
      <LhButton @click="drag = true">draggable arrastrable</LhButton>
      <LhButton @click="strict = true">Cerrar con máscara/Esc deshabilitado</LhButton>
      <LhButton @click="guard = true">Interceptar con beforeClose</LhButton>
      <LhButton @click="noClose = true">showClose=false</LhButton>
    </div>
    <LhDialog v-model="basic" title="Colofón" width="420px" :top="top" :z-index="2000">
      <p style="margin: 0">El diálogo se monta en el body; la máscara y el contenido usan posicionamiento fixed. top controla la distancia superior y zIndex, la capa de apilamiento.</p>
      <template #footer>
        <LhButton @click="basic = false">Cancelar</LhButton>
        <LhButton type="primary" @click="basic = false">Firmar</LhButton>
      </template>
    </LhDialog>
    <LhDialog v-model="center" title="Diálogo centrado" position="center" width="360px" center>
      <p style="margin: 0">position="center" centra verticalmente; center dispone el título y los botones inferiores de forma centrada.</p>
      <template #footer>
        <LhButton type="primary" @click="center = false">Entendido</LhButton>
      </template>
    </LhDialog>
    <LhDialog v-model="bottom" title="Diálogo inferior" position="bottom" width="480px">
      <p style="margin: 0">position="bottom" lo pega al borde inferior; es apto para paneles de acción en dispositivos móviles.</p>
    </LhDialog>
    <LhDialog v-model="full" title="Vista a pantalla completa" fullscreen>
      <p style="margin: 0">fullscreen ocupa toda la ventana gráfica y el área de contenido se adapta a la altura restante.</p>
      <template #footer>
        <LhButton type="primary" @click="full = false">Cerrar</LhButton>
      </template>
    </LhDialog>
    <LhDialog v-model="drag" title="Arrastra por la barra de título" draggable width="420px">
      <p style="margin: 0">Con draggable activado, basta con arrastrar desde la barra de título para mover el diálogo.</p>
    </LhDialog>
    <LhDialog
      v-model="strict"
      title="Modo estricto"
      width="400px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :lock-scroll="true"
    >
      <p style="margin: 0">closeOnClickModal y closeOnPressEscape están desactivados; lockScroll bloquea el desplazamiento de la página y solo se puede cerrar con los botones.</p>
      <template #footer>
        <LhButton type="primary" @click="strict = false">Única salida</LhButton>
      </template>
    </LhDialog>
    <LhDialog v-model="guard" title="Interceptar antes de cerrar" width="400px" :before-close="beforeClose">
      <p style="margin: 0">beforeClose intercepta el cierre: solo se completa al llamar a done() (aquí se demuestra con una doble confirmación).</p>
    </LhDialog>
    <LhDialog v-model="noClose" title="Sin botón de cierre" width="360px" :show-close="false">
      <p style="margin: 0">showClose=false oculta el botón de cierre de la esquina superior derecha.</p>
      <template #footer>
        <LhButton type="primary" @click="noClose = false">Cerrar</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('¿Confirmas el cierre de este diálogo?')) done()
    },
  },
}
</script>

# Props

Prop Descripción Tipo Predeterminado
v-model Visibilidad (model: modelValue/input; también admite el uso estándar de v-model además de :visible.sync) boolean false
title Título string ''
width Ancho string \| number '480px'
position Posición 'top' \| 'center' \| 'bottom' 'center'
center Centra el título y los botones inferiores boolean false
fullscreen A pantalla completa boolean false
showClose Muestra el botón de cierre boolean true
closeOnClickModal / closeOnPressEscape Cerrar con la máscara / con ESC boolean true
draggable Arrastre desde la cabecera (limitado a los bordes de la ventana gráfica) boolean false
lockScroll Bloquea el desplazamiento del body boolean true
beforeClose Intercepta el cierre; se completa al llamar a done() (done) => void —
top Distancia respecto al borde superior (surte efecto con position=top) string '15vh'
zIndex / themeVars / bgPattern / sx Capa de apilamiento y anulaciones de tema — —

# Events

Evento Descripción Parámetro del callback
input Sincronización de la visibilidad del v-model boolean
open Inicio de la apertura (entra en transición) —
opened Fin de la apertura (transición completada) —
close Inicio del cierre (entra en la transición de salida) —
closed Fin del cierre (transición completada) —

# Slots

Slot Descripción
default Cuerpo del contenido
header Título personalizado
footer Área de acciones inferior

# Métodos

Método Descripción
close() Cierra el diálogo
isVisible Visibilidad actual (defineExpose)

Copyright © 2024-2026 FengMo WenXue