# 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
```
**✅ Correcto (Nuxt UI v4):**
```vue
```
#### 2. Slot #content requerido
En v4, el contenido debe ir dentro del slot `#content`.
**❌ Incorrecto:**
```vue
```
**✅ Correcto:**
```vue
```
#### 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
```
**✅ Correcto:**
```vue
```
**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; // Customizar botón cerrar
}
```
### Ejemplo completo
```vue
Cancelar
Guardar
```
---
## Resumen de Cambios Comunes
| Componente | Cambio | Desde | Hacia |
|------------|--------|-------|-------|
| UModal | v-model | `v-model="show"` | `v-model:open="show"` |
| UModal | Contenido | Directo | `` |
| UModal | Ancho custom | `:ui="{ width: 'max-w-4xl' }"` | `:ui="{ content: 'w-[calc(100vw-2rem)] max-w-4xl ...' }"` |
---
## UTabs - Componente de Pestañas
### Cambios de API en v4
#### 1. v-model usa valores string
En Nuxt UI v4, los valores de los tabs deben ser strings, no números.
**❌ Incorrecto:**
```vue
```
**✅ Correcto:**
```vue
```
#### 2. Propiedad `value` en items
Cada item debe tener una propiedad `value` que coincida con el nombre del slot. Si no se especifica, Nuxt UI usa el índice como string ("0", "1", etc.).
**Props de TabsItem:**
```typescript
interface TabsItem {
label?: string
icon?: string
avatar?: AvatarProps
badge?: string | number | BadgeProps
content?: string
value?: string | number // ⚠️ Importante: debe coincidir con el nombre del slot
disabled?: boolean
slot?: string // Nombre del slot personalizado
class?: any
ui?: { ... }
}
```
#### 3. Uso de slots con nombres personalizados
Usa la propiedad `slot` en el item para definir un slot personalizado:
```vue
```
### Ejemplo completo
```vue
```
---
## Auto-import de Componentes en Nuxt
### Convención de nombres para subdirectorios
Cuando organizas componentes en subdirectorios dentro de `app/components/`, Nuxt genera automáticamente nombres prefijados:
**Estructura de archivos:**
```
app/components/
├── lotes/
│ ├── LotesTable.vue
│ ├── LoteForm.vue
│ └── LoteCard.vue
└── operaciones/
├── OperacionesTable.vue
└── OperacionForm.vue
```
**Nombres de componentes generados:**
```vue
```
**Patrón:**
```
```
### NO se requieren imports explícitos
Nuxt hace auto-import automáticamente. **NO** necesitas importar componentes manualmente:
**❌ Incorrecto:**
```vue
```
**✅ Correcto:**
```vue
```
### Verificación con analiticaNucleo
Verificado en el proyecto analiticaNucleo que funciona correctamente:
- `app/components/comercios/TablaComerciosResumen.vue` → ``
- `app/components/comercios/TotalesMonetariosComercio.vue` → ``
---
**Última actualización:** 2025-11-21