Forms are everywhere, and v-model removes the value-plus-listener boilerplate for each field.
`v-model` creates a two-way binding between a form element and a ref. It is sugar for a value binding plus an event listener, chosen per element type:
<input>and<textarea>: bindsvalueand listens toinput.- Checkbox: binds
checked(a boolean). Several checkboxes bound to the same array collect thevalues of the checked ones. - Radio: the ref holds the
valueof the selected radio. <select>: the ref holds the selected option's value, or an array withmultiple.
Modifiers adjust the behaviour:
.trimstrips whitespace..numbercasts the input to a number (when it parses)..lazysyncs onchangeinstead of every keystroke.
v-model ignores any initial value, checked or selected attributes in the template: the JavaScript state is the single source of truth, so set initial values in the ref.
Option values do not have to be strings: bind :value="obj" on options or checkboxes and the model receives the object itself.
For validation, keep it simple at first: a computed errors object derived from the fields, and a submit handler that checks it. Larger forms usually adopt a library such as VeeValidate or FormKit. You will later learn to make your own components work with v-model too.
Example
<script setup>
import { ref, computed } from 'vue'
const name = ref('')
const age = ref(null)
const agree = ref(false)
const toppings = ref(['cheese'])
const size = ref('m')
const canSubmit = computed(() => name.value && agree.value && age.value >= 18)
</script>
<template>
<input v-model.trim="name" placeholder="Name">
<input v-model.number="age" type="number">
<label><input type="checkbox" v-model="agree"> I agree</label>
<label><input type="checkbox" value="cheese" v-model="toppings"> Cheese</label>
<label><input type="checkbox" value="ham" v-model="toppings"> Ham</label>
<select v-model="size">
<option value="s">Small</option><option value="m">Medium</option>
</select>
<pre>{{ { name, age, agree, toppings, size } }}</pre>
<button :disabled="!canSubmit">Order</button>
</template>Remember
v-model= value binding + input listener, adapted to each input type- Several checkboxes on one array ref collect the checked values
.trim,.numberand.lazymodify the binding; initial values live in the ref
Watch out for
- Setting
value="..."orcheckedin the template and expecting it to be the initial state; v-model ignores it.