Completa los datos para registrarte.
{{ error }}
Subiendo…
{{ error }}
El formulario tiene errores
Hay cambios sin guardar
{{ form.values.value }}
```
## Acciones programáticas [Sección titulada «Acciones programáticas»](#acciones-programáticas)
```js
// Setear un valor
form.setValue('email', 'foo@bar.com');
// Setear varios (merge, no replace)
form.setValues({ email: 'foo@bar.com', age: 30 });
// Marcar como touched (muestra errores)
form.touch('email');
form.touchAll();
// Forzar validación
const isOk = form.validate();
// Submit (corre validate + onSubmit)
await form.submit();
// Reset a initialValues + defaults del schema
form.reset();
// Reset a valores específicos
form.reset({ email: 'nuevo@ejemplo.com' });
```
## Schema reactivo [Sección titulada «Schema reactivo»](#schema-reactivo) Si el schema depende de props o state (ej. cambia según el rol del usuario), pasa un **getter**:
```vue
```
Cuando `props.role` cambie, `useForm` reconstruye el controller con el nuevo schema. Los valores existentes se preservan en la medida que sean compatibles con el nuevo schema. ## Initial values [Sección titulada «Initial values»](#initial-values)
```js
const form = useForm(() => ({
schema: { modelSchema: userSchema, locale: 'es' },
initialValues: {
email: 'usuario@empresa.com',
role: 'admin',
newsletter: true,
},
}));
```
`initialValues` se mergea con los `default` del schema. Los valores explícitos siempre ganan sobre los defaults. `isDirty` se calcula contra esta combinación (initialValues + defaults). Si haces `setValue` y luego vuelves al valor inicial, `isDirty` regresa a `false`. ## Submit [Sección titulada «Submit»](#submit)
```vue
```
### Flujo interno del `submit()` [Sección titulada «Flujo interno del submit()»](#flujo-interno-del-submit) 1. `touchAll()` — marca todos los campos como touched (para mostrar todos los errores) 2. `validate()` — re-valida con AJV 3. Si **inválido**: detiene el submit y deja `isSubmitting = false` 4. Si **válido**: setea `isSubmitting = true`, ejecuta `onSubmit(values)`, espera la promise 5. Al finalizar (éxito o error): `isSubmitting = false` ## Subscripción cruda al state [Sección titulada «Subscripción cruda al state»](#subscripción-cruda-al-state) Si necesitas un listener (ej. para logging, telemetría), usa `form.controller.value.subscribe`:
```js
const unsubscribe = form.controller.value.subscribe((state) => {
console.log('form state:', state);
});
onUnmounted(unsubscribe);
```
# Validación
> Cómo funciona AJV, cuándo se valida, locales de error y validación custom.
La validación es **síncrona, schema-driven, traducida** — funciona out-of-the-box sin que escribas un solo validador. ## Motor: AJV 8 [Sección titulada «Motor: AJV 8»](#motor-ajv-8) [AJV](https://ajv.js.org/) es el validador de JSON Schema más rápido y estricto en npm. Cobalt lo configura con: * **`ajv-formats`** para `email`, `date`, `uri`, `uuid`, `regex`, etc. * **`ajv-i18n`** para traducir mensajes de error al locale del usuario. * **`allErrors: true`** para capturar TODOS los errores de un campo, no solo el primero. ## Cuándo se valida [Sección titulada «Cuándo se valida»](#cuándo-se-valida) Por defecto, la validación corre: 1. **En la construcción del form** — para que el state inicial refleje si el form es válido o no (útil para deshabilitar el submit desde el inicio). 2. **En cada `setValue()`** — validación en vivo mientras el usuario escribe. 3. **En `submit()`** — re-valida antes de emitir el evento. Si hay errores, marca todos los campos como `touched` para que el usuario vea todos los mensajes a la vez. Puedes cambiar este comportamiento con la opción `validateOn`:
```js
const form = createForm({
schema: { modelSchema, locale: 'es' },
validateOn: 'blur', // 'change' | 'blur' | 'submit'
});
```
| Valor | Comportamiento | | ---------------------- | ----------------------------------------------------------------------- | | `'change'` *(default)* | Valida en cada `setValue`. UI en vivo. | | `'blur'` | Valida solo cuando el campo pierde foco. Menos ruido para forms largos. | | `'submit'` | Solo valida en `submit()`. Modo “old school”. | ## Errores [Sección titulada «Errores»](#errores) El state expone `errors` como `Record