🪝 useField Composable

useField is a headless binding for a single form field. It resolves the formik instance from a prop or Vue injection and gives you a reactive value, error/touched state, ready-made event handlers, and accessibility attributes — so you can wire any input to Vue Formik without the bundled components.

The built-in components (FormInput, FormTextArea, FormSelectField, FormContentEditable) are themselves built on useField.

📦 Usage

Tip: pass a getter for reactive names

When the field name comes from a prop, pass a getter — useField(() => props.name) — so the binding stays reactive if the name changes.

🧱 Building a custom input

🌳 Parent schema, child inputs (recommended pattern)

The cleanest way to build forms is to declare the schema and form state once in a parent, then let small input components bind to individual fields with useField. The children don't know anything about the schema — they only reference a field name, and validation errors flow down automatically.

This works because <FormikForm> provides the formik instance via Vue's provide(), and useField picks it up with inject('formik').

1. Parent owns the schema

2. Child binds to a field

Each field's error comes from the parent's schema — define the rules in one place, reuse the input everywhere.

How errors reach the input

The parent's zodSchema (or yupSchema, standardSchema, validationSchema, …) produces an errors object keyed by field path. useField('email') reads errors.email for you and exposes it as error / hasError — which only becomes truthy once the field is also touched.

Without a FormikForm wrapper

If you're not wrapping fields in <FormikForm>, either provide('formik', formik) yourself in the parent, or pass the instance to each field explicitly via the formik option:

🔌 Wrapping a third-party component

Because value is a writable ref, it works directly with v-model on UI-library components (Vuetify, PrimeVue, Element Plus, …).

✅ Field-level validation

Pass a validation rule to validate this field. It runs alongside any schema validation and takes precedence for its own field, and is cleaned up automatically on unmount.