Fix: Actualizar implementación de UTabs a Nuxt UI v4
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s
- Cambiar selectedTab de ref(0) a ref('lotes') para usar string
- Agregar propiedad value explícita a cada tab item
- Crear documento nuxt-ui-tips.md con documentación de cambios
- Los valores deben ser strings según API de v4
This commit is contained in:
173
nuxt-ui-tips.md
Normal file
173
nuxt-ui-tips.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Nuxt UI v4 - Tips y Cambios de API
|
||||
|
||||
Este documento contiene los cambios más comunes al migrar o trabajar con Nuxt UI v4, basado en la experiencia práctica del proyecto.
|
||||
|
||||
## UModal - Componente Modal
|
||||
|
||||
### Cambios de API en v4
|
||||
|
||||
#### 1. v-model actualizado a v-model:open
|
||||
|
||||
**❌ Incorrecto (API antigua):**
|
||||
```vue
|
||||
<UModal v-model="showModal">
|
||||
<!-- contenido -->
|
||||
</UModal>
|
||||
```
|
||||
|
||||
**✅ Correcto (Nuxt UI v4):**
|
||||
```vue
|
||||
<UModal v-model:open="showModal">
|
||||
<!-- contenido -->
|
||||
</UModal>
|
||||
```
|
||||
|
||||
#### 2. Slot #content requerido
|
||||
|
||||
En v4, el contenido debe ir dentro del slot `#content`.
|
||||
|
||||
**❌ Incorrecto:**
|
||||
```vue
|
||||
<UModal v-model:open="showModal">
|
||||
<MiComponente />
|
||||
</UModal>
|
||||
```
|
||||
|
||||
**✅ Correcto:**
|
||||
```vue
|
||||
<UModal v-model:open="showModal">
|
||||
<template #content>
|
||||
<MiComponente />
|
||||
</template>
|
||||
</UModal>
|
||||
```
|
||||
|
||||
#### 3. Prop :ui para personalización
|
||||
|
||||
La prop `:ui` no tiene un slot `width`. Para personalizar el ancho, debes usar el slot `content`.
|
||||
|
||||
**❌ Incorrecto:**
|
||||
```vue
|
||||
<UModal
|
||||
v-model:open="showModal"
|
||||
:ui="{ width: 'max-w-4xl' }"
|
||||
>
|
||||
<!-- contenido -->
|
||||
</UModal>
|
||||
```
|
||||
|
||||
**✅ Correcto:**
|
||||
```vue
|
||||
<UModal
|
||||
v-model:open="showModal"
|
||||
:ui="{ content: 'w-[calc(100vw-2rem)] max-w-4xl rounded-lg shadow-lg ring ring-default' }"
|
||||
>
|
||||
<template #content>
|
||||
<!-- contenido -->
|
||||
</template>
|
||||
</UModal>
|
||||
```
|
||||
|
||||
**Nota:** Las clases del tema por defecto son:
|
||||
- `w-[calc(100vw-2rem)]` - ancho responsive
|
||||
- `rounded-lg` - bordes redondeados
|
||||
- `shadow-lg` - sombra
|
||||
- `ring ring-default` - borde/anillo
|
||||
|
||||
Luego agregas tu clase de ancho máximo personalizado: `max-w-3xl`, `max-w-4xl`, etc.
|
||||
|
||||
### Slots disponibles en UModal
|
||||
|
||||
Según la documentación oficial de Nuxt UI v4:
|
||||
|
||||
```typescript
|
||||
interface ModalSlots {
|
||||
default(): any; // Elemento trigger (opcional)
|
||||
content(): any; // Contenido completo del modal
|
||||
header(): any; // Solo el header
|
||||
title(): any; // Solo el título
|
||||
description(): any; // Solo la descripción
|
||||
actions(): any; // Acciones del header
|
||||
close(): any; // Botón de cerrar
|
||||
body(): any; // Solo el cuerpo
|
||||
footer(): any; // Solo el footer
|
||||
}
|
||||
```
|
||||
|
||||
### Props importantes
|
||||
|
||||
```typescript
|
||||
interface ModalProps {
|
||||
open?: boolean; // Estado del modal (usar con v-model:open)
|
||||
defaultOpen?: boolean; // Estado inicial
|
||||
modal?: boolean; // Bloquea interacción fuera (default: true)
|
||||
overlay?: boolean; // Mostrar overlay (default: true)
|
||||
dismissible?: boolean; // Cerrar al hacer clic fuera (default: true)
|
||||
transition?: boolean; // Animación (default: true)
|
||||
fullscreen?: boolean; // Pantalla completa
|
||||
scrollable?: boolean; // Contenido scrollable (v4.2+)
|
||||
title?: string; // Título del modal
|
||||
description?: string; // Descripción del modal
|
||||
close?: boolean | Partial<ButtonProps>; // Customizar botón cerrar
|
||||
}
|
||||
```
|
||||
|
||||
### Ejemplo completo
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- Modal básico con título y descripción -->
|
||||
<UModal
|
||||
v-model:open="showBasicModal"
|
||||
title="Crear Nuevo Lote"
|
||||
description="Complete el formulario para crear un lote"
|
||||
>
|
||||
<template #body>
|
||||
<LoteForm @submit="handleSubmit" />
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<UButton @click="showBasicModal = false" variant="outline">
|
||||
Cancelar
|
||||
</UButton>
|
||||
<UButton @click="handleSubmit">
|
||||
Guardar
|
||||
</UButton>
|
||||
</template>
|
||||
</UModal>
|
||||
|
||||
<!-- Modal con contenido personalizado y ancho custom -->
|
||||
<UModal
|
||||
v-model:open="showCustomModal"
|
||||
:ui="{ content: 'w-[calc(100vw-2rem)] max-w-4xl rounded-lg shadow-lg ring ring-default' }"
|
||||
>
|
||||
<template #content>
|
||||
<MiComponenteCustom />
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const showBasicModal = ref(false)
|
||||
const showCustomModal = ref(false)
|
||||
|
||||
const handleSubmit = () => {
|
||||
// lógica
|
||||
showBasicModal.value = false
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Resumen de Cambios Comunes
|
||||
|
||||
| Componente | Cambio | Desde | Hacia |
|
||||
|------------|--------|-------|-------|
|
||||
| UModal | v-model | `v-model="show"` | `v-model:open="show"` |
|
||||
| UModal | Contenido | Directo | `<template #content>` |
|
||||
| UModal | Ancho custom | `:ui="{ width: 'max-w-4xl' }"` | `:ui="{ content: 'w-[calc(100vw-2rem)] max-w-4xl ...' }"` |
|
||||
|
||||
---
|
||||
|
||||
**Última actualización:** 2025-11-21
|
||||
Reference in New Issue
Block a user