Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tanstack/form/llms.txt

Use this file to discover all available pages before exploring further.

The useForm composable is the primary way to create and manage forms in Vue applications using TanStack Form.

Import

import { useForm } from '@tanstack/vue-form'

Signature

function useForm<
  TParentData,
  TFormOnMount extends undefined | FormValidateOrFn<TParentData>,
  TFormOnChange extends undefined | FormValidateOrFn<TParentData>,
  TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnBlur extends undefined | FormValidateOrFn<TParentData>,
  TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnSubmit extends undefined | FormValidateOrFn<TParentData>,
  TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnDynamic extends undefined | FormValidateOrFn<TParentData>,
  TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TParentData>,
  TFormOnServer extends undefined | FormAsyncValidateOrFn<TParentData>,
  TSubmitMeta,
>(
  opts?: FormOptions<
    TParentData,
    TFormOnMount,
    TFormOnChange,
    TFormOnChangeAsync,
    TFormOnBlur,
    TFormOnBlurAsync,
    TFormOnSubmit,
    TFormOnSubmitAsync,
    TFormOnDynamic,
    TFormOnDynamicAsync,
    TFormOnServer,
    TSubmitMeta
  >,
): VueFormExtendedApi<...>

Parameters

opts
FormOptions<TFormData>
Optional configuration object for the form.
opts.defaultValues
TFormData
Initial values for the form fields.
opts.onSubmit
(values: FormSubmitData<TFormData>) => void | Promise<void>
Callback function called when the form is submitted.
opts.validators
FormValidators<TFormData>
Validation functions for the form.
opts.validators.onChange
FormValidateOrFn<TFormData>
Validator that runs on every change.
opts.validators.onChangeAsync
FormAsyncValidateOrFn<TFormData>
Async validator that runs on change with debouncing.
opts.validators.onBlur
FormValidateOrFn<TFormData>
Validator that runs when the form loses focus.
opts.validators.onMount
FormValidateOrFn<TFormData>
Validator that runs when the form is mounted.

Return Value

api
VueFormExtendedApi<TFormData>
The form API instance with Vue-specific extensions.
Field
FieldComponent<TFormData>
A Vue component for rendering individual form fields.
useField
UseField<TFormData>
A composable for creating and managing individual fields.
useStore
(selector?) => Readonly<Ref<TSelected>>
A composable for subscribing to form state changes.
Subscribe
Component
A component for subscribing to form state.
handleSubmit
() => void
Function to trigger form submission.
reset
() => void
Function to reset the form to its initial state.
state
FormState<TFormData>
Current state of the form including values, errors, and validation status.

Usage Example

<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'

interface FormData {
  firstName: string
  lastName: string
}

const form = useForm<FormData>({
  defaultValues: {
    firstName: '',
    lastName: '',
  },
  onSubmit: async ({ value }) => {
    // Submit form data
    console.log('Form submitted:', value)
  },
})
</script>

<template>
  <form
    @submit="
      (e) => {
        e.preventDefault()
        e.stopPropagation()
        form.handleSubmit()
      }
    "
  >
    <form.Field
      name="firstName"
      :validators="{
        onChange: ({ value }) =>
          !value
            ? 'A first name is required'
            : value.length < 3
              ? 'First name must be at least 3 characters'
              : undefined,
      }"
    >
      <template v-slot="{ field, state }">
        <label :htmlFor="field.name">First Name:</label>
        <input
          :id="field.name"
          :name="field.name"
          :value="field.state.value"
          @input="
            (e) => field.handleChange((e.target as HTMLInputElement).value)
          "
          @blur="field.handleBlur"
        />
        <div v-if="state.meta.errors.length" style="color: red">
          {{ state.meta.errors[0] }}
        </div>
      </template>
    </form.Field>

    <form.Subscribe>
      <template v-slot="{ canSubmit, isSubmitting }">
        <button type="submit" :disabled="!canSubmit">
          {{ isSubmitting ? '...' : 'Submit' }}
        </button>
      </template>
    </form.Subscribe>
  </form>
</template>

See Also