Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vuetifyjs/vuetify/llms.txt

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

VForm

The VForm component provides form validation, state management, and coordination of form inputs. It works with all Vuetify input components that support validation.

Basic Usage

<template>
  <VForm v-model="valid" @submit.prevent="onSubmit">
    <VTextField
      v-model="name"
      label="Name"
      :rules="[v => !!v || 'Name is required']"
    />
    
    <VTextField
      v-model="email"
      label="Email"
      :rules="emailRules"
    />
    
    <VBtn
      type="submit"
      :disabled="!valid"
    >
      Submit
    </VBtn>
  </VForm>
</template>

<script setup>
import { ref } from 'vue'

const valid = ref(false)
const name = ref('')
const email = ref('')

const emailRules = [
  v => !!v || 'Email is required',
  v => /.+@.+\..+/.test(v) || 'Email must be valid',
]

function onSubmit() {
  if (valid.value) {
    console.log('Form submitted', { name: name.value, email: email.value })
  }
}
</script>

Props

modelValue
boolean | null
The validation state of the form. true when all fields are valid, false when any field is invalid, null when fields haven’t been validated yet.
disabled
boolean
default:"false"
Disable all form inputs.
readonly
boolean
default:"false"
Make all form inputs readonly.
fastFail
boolean
default:"false"
Stop validation at the first error instead of validating all fields.
validateOn
'input' | 'blur' | 'submit'
default:"input"
When to trigger validation on form inputs.

Validation Rules

Validation rules are functions that return true when valid or an error message string when invalid:
<template>
  <VForm v-model="valid">
    <VTextField
      v-model="username"
      label="Username"
      :rules="usernameRules"
    />
    
    <VTextField
      v-model="password"
      label="Password"
      type="password"
      :rules="passwordRules"
    />
  </VForm>
</template>

<script setup>
import { ref } from 'vue'

const valid = ref(false)
const username = ref('')
const password = ref('')

const usernameRules = [
  v => !!v || 'Username is required',
  v => (v && v.length >= 3) || 'Username must be at least 3 characters',
  v => /^[a-zA-Z0-9_]+$/.test(v) || 'Username must be alphanumeric',
]

const passwordRules = [
  v => !!v || 'Password is required',
  v => (v && v.length >= 8) || 'Password must be at least 8 characters',
  v => /[A-Z]/.test(v) || 'Password must contain an uppercase letter',
  v => /[0-9]/.test(v) || 'Password must contain a number',
]
</script>

Manual Validation

You can manually trigger validation using a template ref:
<template>
  <VForm ref="form" v-model="valid">
    <VTextField
      v-model="email"
      label="Email"
      :rules="emailRules"
    />
    
    <VBtn @click="validate">Validate</VBtn>
    <VBtn @click="reset">Reset</VBtn>
    <VBtn @click="resetValidation">Reset Validation</VBtn>
  </VForm>
</template>

<script setup>
import { ref } from 'vue'

const form = ref(null)
const valid = ref(false)
const email = ref('')

const emailRules = [
  v => !!v || 'Email is required',
  v => /.+@.+\..+/.test(v) || 'Email must be valid',
]

async function validate() {
  const { valid } = await form.value.validate()
  console.log('Form is valid:', valid)
}

function reset() {
  form.value.reset()
}

function resetValidation() {
  form.value.resetValidation()
}
</script>

Form Submission

The form emits a special submit event that includes the validation promise:
<template>
  <VForm @submit="onSubmit">
    <VTextField
      v-model="name"
      label="Name"
      :rules="[v => !!v || 'Required']"
    />
    
    <VBtn type="submit">Submit</VBtn>
  </VForm>
</template>

<script setup>
import { ref } from 'vue'

const name = ref('')

async function onSubmit(event) {
  // The event has been augmented with validation promise methods
  const { valid } = await event
  
  if (valid) {
    console.log('Form is valid, submitting...')
    // Submit form data
  } else {
    console.log('Form has errors')
  }
}
</script>

Fast Fail

Stop validation at the first error for better performance with large forms:
<template>
  <VForm v-model="valid" fast-fail>
    <!-- Validation will stop at first error -->
    <VTextField
      v-for="i in 50"
      :key="i"
      :label="`Field ${i}`"
      :rules="[v => !!v || 'Required']"
    />
  </VForm>
</template>

Validation Timing

Control when validation runs:
<template>
  <div>
    <!-- Validate on input (default) -->
    <VForm validate-on="input">
      <VTextField label="Validates on input" />
    </VForm>
    
    <!-- Validate on blur -->
    <VForm validate-on="blur">
      <VTextField label="Validates on blur" />
    </VForm>
    
    <!-- Validate only on submit -->
    <VForm validate-on="submit">
      <VTextField label="Validates on submit" />
    </VForm>
  </div>
</template>

Nested Forms

Form inputs can be nested in components and will still be registered:
<!-- UserForm.vue -->
<template>
  <VForm v-model="valid">
    <UserFields />
    <AddressFields />
    
    <VBtn
      type="submit"
      :disabled="!valid"
    >
      Submit
    </VBtn>
  </VForm>
</template>

Events

update:modelValue
(valid: boolean | null) => void
Emitted when the form validation state changes.
submit
(e: SubmitEventPromise) => void
Emitted when the form is submitted. The event object includes validation promise methods.

Methods

validate
() => Promise<FormValidationResult>
Validates all form inputs and returns a promise with the result.
reset
() => void
Resets all form inputs to their initial values.
resetValidation
() => void
Clears validation errors without resetting input values.

Slots

default
{ errors, isDisabled, isReadonly, isValidating, isValid, items, validate, reset, resetValidation }
The default slot provides access to form state and methods.

Composable: useForm

The useForm composable allows child components to access the parent form’s state:
import { useForm } from 'vuetify'

const form = useForm()

// Access form state
const isDisabled = form.isDisabled
const isReadonly = form.isReadonly
Source: ~/workspace/source/packages/vuetify/src/composables/form.ts:195

Build docs developers (and LLMs) love