Vuetify 3 – Forms & Inputs
v-form with validation
<template>
<v-form ref="form" v-model="valid" @submit.prevent="onSubmit">
<v-text-field
v-model="email"
label="Email"
type="email"
:rules="emailRules"
required
/>
<v-text-field
v-model="password"
label="Password"
type="password"
:rules="passwordRules"
required
/>
<v-btn type="submit" color="primary" :disabled="!valid">Sign in</v-btn>
</v-form>
</template>
<script>
export default {
data() {
return {
valid: false,
email: '',
password: '',
emailRules: [
(v) => !!v || 'Email is required',
(v) => /.+@.+\..+/.test(v) || 'Email must be valid',
],
passwordRules: [
(v) => !!v || 'Password is required',
(v) => (v && v.length >= 8) || 'Min 8 characters',
],
}
},
methods: {
async onSubmit() {
const { valid } = await this.$refs.form.validate()
if (!valid) return
await this.login()
},
},
}
</script>
Important Vue 3 / Vuetify 3 changes
<v-form ref="form">.validate()is async in Vuetify 3 — it returnsPromise<{ valid, errors }>. (Vue 2 / Vuetify 2 returned synchronous bool.)- Inputs use
v-modelandlabel;:rulesis an array of functions returningtrue | string(the message).
Reset / clear
this.$refs.form.reset() // clears values
this.$refs.form.resetValidation() // clears error state, keeps values
Common inputs
v-text-field
<v-text-field
v-model="search"
label="Search"
prepend-inner-icon="mdi-magnify"
clearable
variant="outlined"
density="comfortable"
/>
v-textarea
<v-textarea
v-model="notes"
label="Notes"
rows="3"
auto-grow
counter="500"
/>
v-select
<v-select
v-model="status"
:items="['draft', 'active', 'archived']"
label="Status"
/>
With objects:
<v-select
v-model="userId"
:items="users"
item-title="name"
item-value="id"
label="Owner"
/>
item-title / item-value replaced Vuetify 2's item-text / item-value.
v-autocomplete
Same API as v-select, but adds typed-search filtering.
<v-autocomplete
v-model="userId"
:items="users"
item-title="name"
item-value="id"
label="Owner"
:loading="loading"
@update:search="onSearchInput"
/>
v-checkbox / v-switch / v-radio-group
<v-checkbox v-model="agreed" label="I agree" :rules="[v => !!v || 'Required']" />
<v-switch v-model="darkMode" label="Dark mode" color="primary" />
<v-radio-group v-model="size" inline>
<v-radio label="S" value="s" />
<v-radio label="M" value="m" />
<v-radio label="L" value="l" />
</v-radio-group>
v-date-picker (date input)
<v-text-field
v-model="dateText"
label="Date"
readonly
@click="showDatePicker = true"
/>
<v-dialog v-model="showDatePicker" max-width="320">
<v-date-picker v-model="date" @update:model-value="onDate" />
</v-dialog>
Variants
Most inputs accept variant: outlined (KYD default), filled, solo,
underlined, plain. Combine with density: default, comfortable, compact.