✨ useFormik Composable

The useFormik composable is your ultimate ally for managing complex forms in Vue 3 applications. With its simplicity and efficiency, it provides:

  • ⚑ Reactive state management
  • βœ… Schema-based validation (supporting libraries like Yup)
  • πŸš€ Streamlined form submission handling

With useFormik, you can effortlessly create dynamic, user-friendly forms that deliver a robust and consistent user experience.

Performance:

Form validation runs deeply on every value change. To keep things snappy, optimize your validation schema and rules.

πŸ› οΈ Parameters

ParameterTypeRequiredDefaultDescription
initialValuesTtrue-An object containing the initial values for the form fields.
validateOnMountbooleanfalsetrueIf true, performs validation when the form is initialized.
validateOnChangebooleanfalsetrueIf true, performs validation when form fields change.
validateOnBlurbooleanfalsetrueIf true, performs validation when form fields lose focus.
validationDebouncenumberfalse0Debounce time in milliseconds for validation when validateOnChange is true.
preventDefaultbooleanfalsetrueIf true, prevents the default form submission behavior.
onSubmitFormikOnSubmit<T>false-A function to handle form submission. It receives the current form values and helpers and may return a Promise for async workflows.
yupSchemaObjectSchema<T>false-A yup schema for validating the form fields.
joiSchemaObjectSchema<T>false-A joi schema for validating the form fields.
zodSchemaZodType<T>false-A zod schema for validating the form fields.
structSchemaStruct<T>false-A superstruct schema for validating the form fields.
validationSchemaFormikValidationSchema<T>false-A custom validation rules object or function for validating the form fields. Supports synchronous or asynchronous rules.
initialErrorsPartial<Record<keyof T, unknown>>false-Initial error values for form fields.
initialTouchedPartial<Record<keyof T, unknown>>false-Initial touched state values for form fields.

πŸ”— Notes:

The validation schema can be supplied as yupSchema, joiSchema, zodSchema, structSchema, or validationSchema parameters.

If any of the schema parameters are not provided, the form will not perform any validation.

Please use Object schemas for Yup and Joi and not the string schemas.

Custom validation rules and schema adapters may return promises; the form will await their resolution before updating errors.

Parameters for onSubmit handler

TYPE: (FormikOnSubmit<T> = values: T, helpers: FormikHelpers<T>)

When the onSubmit function is invoked by the submit handler, it receives two arguments: values and helpers.

The values argument is an object that contains the current values of the form fields.

The helpers argument is an object that contains a set of utility functions that can be used to interact with the form state.

  1. reset - Resets the form to its initial state.
  2. setErrors - Sets the errors for the form fields.
  3. setValues - Sets the values for the form fields. Accepts an optional { replace?: boolean } parameter to fully replace the current values.
  4. setSubmitting - Sets the submitting state of the form.
  5. setTouched - Sets the touched state of the form fields.
  6. setFieldValue - Sets the value of a specific form field.
  7. setFieldTouched - Sets the touched state of a specific form field.
  8. event - The event that triggered the form submission or reset.

πŸ—οΈ Properties

PropertyTypeDescription
valuesreactive<T>Reactive object containing the current values of form fields.
errorsreactive<object>Reactive object containing field-level validation errors.
touchedreactive<object>Reactive object indicating whether a field has been interacted with.
isValidcomputed<boolean>Computed property indicating if the form is valid.
isDirtycomputed<boolean>Computed property indicating if the form values have changed from the initial values.
isSubmittingref<boolean>Ref indicating if the form is in the submitting state. Automatically resets after validation failures or when async submits resolve.
isValidatingref<boolean>Ref indicating if the form is in the validating state.
submitCountref<number>Ref containing the number of form submission attempts.
fieldHandlerscomputed<object>Handlers (onBlur and onChange) for form fields.

πŸ”— Notes:

  1. Reactivity: Values, errors, and touched objects are fully reactive, enabling two-way data binding with form fields.
  2. Computed properties: isValid & isDirty are computed properties. Don't forget to use .value while accessing it inside the template.

βš™οΈ Methods

MethodParametersDescription
setValues(newValues: Partial<T>, options?: { replace?: boolean })Updates the form values. Use `replace: true` to fully replace the current values and drop keys that are not present in the new payload.
setErrors(newErrors: object)Updates the form errors.
setTouched(newTouched: object)Updates the form’s touched state.
reset({ values, keepTouched }: IResetOptions<T>)Resets the form to the initial state or provided values. When new values are provided they become the new initial state and replace missing keys.
setFieldValue(field: string, value: unknown)Updates the value of a specific field.
setFieldTouched(field: string, touchedValue: boolean)Marks a specific field as touched.
setSubmitting(value: boolean)Updates the submitting state.
handleSubmit(e: Event)Handles form submission, triggers validation, and executes onSubmit. Returns a Promise that resolves after async validation and submission complete.
handleFieldBlur(e: FocusEvent)Marks the corresponding field as touched on blur.
handleFieldChange(e: Event)Updates the corresponding field’s value and marks it as touched on change.
hasFieldError(field: string): booleanChecks if a specific field has an error and has been touched.
getFieldError(field: string): stringRetrieves the error message for a specific field if it exists.
getFieldValue(field: string): unknownRetrieves the current value of a specific field.
getFieldTouched(field: string): boolean|undefinedChecks if a specific field has been touched.

🌟 Dynamic Fields:

  1. setFieldValue: Dynamically update specific field values.
  2. setFieldTouched: Dynamically update the touched state of specific fields.
  3. ⚠️ setFieldError: This method is NOT available. Errors are handled internally through validation rules in the schema.

πŸ” Custom Validation

You can define custom validation rules using the validationSchema parameter. These rules can validate simple fields, arrays, objects, or even arrays of objects.

Example

The above example shows a validation schema for the email and password fields. - **Email** must be valid and is required. - **Password** must be at least 8 characters long and is required.

Validation schemas can be customized to handle simple fields or more complex structures, such as arrays or nested objects.

πŸ’‘ My form values aren’t always strings

No worries! Validation rules can be written for arrays, objects, or even arrays of objects.

In the example above, the emails field is an array of email addresses. Each email is validated, and errors are displayed if any email is invalid.

For more complex validation rules, check out the playground section. πŸ”—

⚑ Async Validation & Debouncing

Vue Formik supports both synchronous and asynchronous validation, along with debouncing to optimize performance and user experience.

πŸ”„ Asynchronous Validation

You can use async validation rules to perform server-side validation, check data availability, or validate complex business logic that requires network requests.

Key Points:

  • Validation functions can return Promise objects (async/await syntax or explicit promises)
  • The isValidating flag is automatically set to true during validation
  • All promises are awaited before updating the error state
  • Works with all schema types: custom, Yup, Joi, Zod, and Superstruct

⏱️ Debounced Validation

When validateOnChange is enabled, validation runs on every field change. For performance optimization and better UX, you can debounce validation to wait for users to finish typing.

How Debouncing Works:

  • validationDebounce sets the delay in milliseconds (default: 0 = no debounce)
  • Validation runs only after the user stops typing for the specified duration
  • Rapid value changes cancel previous debounced validations
  • Only the final value is validated, reducing unnecessary validation calls
  • Works with both sync and async validation rules

🎯 Combined Example

You can combine async validation with debouncing for optimal performance:

This approach is perfect for scenarios like username availability checks, email validation, or any form with search-like fields that trigger API calls.

Performance Tip:

For forms with heavy validation logic or API calls, always use debouncing with validateOnChange. The recommended debounce time is between 200-500ms depending on your validation complexity.