fn
useForm
v0.0.14testeddemoHeadless, performant form state management. Holds reactive values,
flat path-keyed errors/touched maps, derived meta, and a full set of
mutation/validation/submit/reset helpers. Validation accepts a
Standard Schema
(zod/valibot/arktype), a custom resolver, or per-field function validators.
Examples
ts
const { values, errors, handleSubmit } = useForm({
initialValues: { email: '', age: 0 },
schema: z.object({ email: z.string().email(), age: z.number().min(18) }),
});
const onSubmit = handleSubmit((output) => save(output));ts
// Inline binding with defineField
const form = useForm({ initialValues: { name: '' } });
const [name, nameProps] = form.defineField('name');
// <input v-model="name" v-bind="nameProps">Demo
Loading demo…
Signature
ts
export function useForm<TInput extends object, TOutput = TInput>(
options: UseFormOptions<TInput, TOutput> ={ ... }Type Parameters
TInputextends objectTOutput= TInputParameters
| Parameter | Type | Description |
|---|---|---|
options? | UseFormOptions<TInput, TOutput> | Initial values, schema/resolver, and validation triggers |
Returns
UseFormReturn<TInput, TOutput>The reactive form instance (also provided to descendant fields)| Property | Type | Description |
|---|---|---|
values | TInput | Reactive form values. Bind directly with v-model="values.path". |
errors | ComputedRef<FormErrors> | Flat, reactive map of path → error messages. |
meta | ComputedRef<FormMeta> | Grouped reactive meta flags for the whole form. |
isDirty | ComputedRef<boolean> | Whether any value differs from the initial snapshot. |
isValid | ComputedRef<boolean> | Whether the form has no errors. |
isValidating | Readonly<Ref<boolean>> | Whether a validation run is in flight. |
isSubmitting | Readonly<Ref<boolean>> | Whether a submit is in flight. |
submitCount | Readonly<Ref<number>> | Number of times submit has been attempted. |
getFieldValue | <P extends FieldPath<TInput>>(path: P) => FieldPathValue<TInput, P> | Read a field value by path. |
getError | (path: FieldPath<TInput>) => string | undefined | The first error message for a path, if any. |
getErrors | (path: FieldPath<TInput>) => string[] | All error messages for a path (empty array when none). |
isFieldDirty | (path: FieldPath<TInput>) => boolean | Whether a field differs from its initial snapshot. |
isFieldTouched | (path: FieldPath<TInput>) => boolean | Whether a field has been touched. |
isFieldValid | (path: FieldPath<TInput>) => boolean | Whether a field currently has no errors. |
setFieldValue | <P extends FieldPath<TInput>>( path: P, value: FieldPathValue<TInput, P>, options?: SetValueOptions, ) => void | Write a field value by path. |
setValues | (values: PartialDeep<TInput>, options?: { merge?: boolean }) => void | Merge or replace multiple values at once. |
setFieldError | (path: FieldPath<TInput>, message: string | string[] | null) => void | Set or clear (with null) a field's error messages. |
setErrors | (errors: FormErrors) => void | Replace the entire error map. |
setFieldTouched | (path: FieldPath<TInput>, touched?: boolean) => void | Mark a field touched/untouched. |
setTouched | (touched?: boolean) => void | Mark all known fields touched/untouched. |
validate | () => Promise<FormValidationResult<TOutput>> | Validate the whole form. |
validateField | (path: FieldPath<TInput>) => Promise<FieldValidationResultDetail> | Validate a single field (runs the pipeline, updates that field's errors). |
resetForm | (state?: FormResetState<TInput>) => void | Reset the form to its initial (or provided) state. |
resetField | <P extends FieldPath<TInput>>(path: P, value?: FieldPathValue<TInput, P>) => void | Reset a single field to its initial (or provided) value. |
handleSubmit | ( onValid: SubmissionHandler<TOutput>, onInvalid?: InvalidSubmissionHandler, ) => (event?: Event) => Promise<void> | Wrap a submit callback: validates, then calls onValid with typed output
(or onInvalid with the error map). |
handleReset | (event?: Event) => void | Reset handler suitable for a <form>'s reset event. |
defineField | <P extends FieldPath<TInput>>( path: P, options?: DefineFieldOptions<FieldPathValue<TInput, P>, TInput>, ) => [Ref<FieldPathValue<TInput, P>>, ComputedRef<FieldBindingProps>] | Bind a field inline: returns [model, props] for v-model + v-bind. |
formProps | { onSubmit: (event: Event) => void; onReset: (event: Event) => void; novalidate: boolean; } | Props to spread on the <form> element (@submit/@reset/novalidate). |
_registerValidator | (path: string, validator: FieldValidator) => void | — |
_unregisterValidator | (path: string, validator: FieldValidator) => void | — |
_shouldValidate | (trigger: Exclude<ValidationTrigger, 'manual'>) => boolean | — |
_remapFieldPaths | (basePath: string, indexMap: (index: number) => number | null) => void | — |