Ejemplo Práctico: Componente Modal
Imagina que quieres crear un componente modal que se pueda abrir y cerrar desde un componente padre. Para ello, definiremos dos métodos: open y close, que manipulan un estado reactivo isOpen que controla la visibilidad del modal. Con defineExpose() haremos que estos métodos sean accesibles desde el exterior.
Código del componente Modal
<script setup lang="ts">
import { ref } from 'vue'
const isOpen = ref(false)
const open = () => {
isOpen.value = true
}
const close = () => {
isOpen.value = false
}
defineExpose({
open,
close
})
</script>
<template>
<div
v-if="isOpen"
class="fixed inset-0 flex items-center justify-center bg-gray-800 bg-opacity-75"
>
<div class="bg-white p-6 rounded-lg shadow-lg">
<slot />
<button
class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700"
@click="close"
>
Cerrar
</button>
</div>
</div>
</template>Explicación del Código
Plantilla (Template):
Se utilizav-if="isOpen"para mostrar u ocultar el modal según el estado de la variablevisible. Además, se define un slot para permitir la inserción de contenido personalizado y se añade un botón que cierra el modal al hacer clic.Script Setup:
Se importa
refde Vue para crear una variable reactivaisOpen.Se definen dos funciones,
openyclose, que modifican el estado del modal.Se llama a
defineExpose({ open, close })para que estos métodos sean accesibles desde el componente padre a través de una referencia.
Uso desde el Componente Padre
Para utilizar este modal, podrías tener un componente padre que lo importe y lo controle mediante una referencia:
<script setup lang="ts">
import { useTemplateRef } from 'vue'
import MyModal from '@/components/MyModal.vue'
const myModal = useTemplateRef('myModalRef')
const handleOpenModal = () => {
myModal.value?.open()
}
</script>
<template>
<main class="flex items-center justify-center flex-col gap-4 h-screen">
<button @click="handleOpenModal">
Abrir modal
</button>
<MyModal ref="myModalRef" />
</main>
</template>En este ejemplo, al hacer clic en el botón "Abrir Modal", se invoca el método open() expuesto desde el componente Modal, lo que cambia el estado de isOpen y muestra el modal.
Conclusión
El uso de defineExpose() en Vue 3 con <script setup> es una herramienta poderosa que permite mantener el encapsulamiento del componente sin sacrificar la flexibilidad de exponer ciertas funcionalidades a componentes padres. Con este enfoque, es posible crear componentes modulares y reutilizables, como en el ejemplo del modal, donde los métodos open y close se pueden invocar externamente para controlar su comportamiento.
Sigue leyendo
Una idea lleva a otra.
)
defineModel() en Vue 3.4+: La evolución elegante del v-model en componentes
)
¿Qué es un Composable?
)
)