Forms & v-model
Binding an input's value and listening for it to change is common enough that Vue gives it a single directive, v-model, which keeps a form field and a piece of data in sync in both directions.
v-model on a text input
Without v-model, you'd bind the input's value with :value and separately listen for an @input event to write it back — v-model does both at once:
<input v-model="username">
<p>You typed: {{ username }}</p>
You typed: s You typed: sa You typed: sam
Typing in the input updates this.username immediately, and because it's reactive, anything else in the template that reads username (like the paragraph above) updates right along with it.
v-model on other input types
v-model adapts to whatever kind of form element it's on — a checkbox binds to a boolean, a group of radios binds to whichever value is selected, and a select binds to the chosen option's value:
<input type="checkbox" v-model="subscribed"> Subscribe to updates <select v-model="country"> <option value="in">India</option> <option value="us">United States</option> </select>
Here subscribed holds true/false, and country holds whichever option's value attribute is currently selected — "in" or "us", not the visible text.
Submitting a form
Combine v-model on each field with the @submit.prevent modifier from the event-handling lesson to build a complete, controlled form:
<form @submit.prevent="handleSubmit"> <input v-model="email" type="email" placeholder="Email"> <button type="submit">Sign up</button> </form>
methods: {
handleSubmit() {
console.log('Submitting:', this.email)
}
}
v-model is really just shorthand — on a text input it expands to :value="username" plus @input="username = $event.target.value". Knowing that expansion is useful once you write a custom component that wants to support v-model itself: it just needs to accept a modelValue prop and emit an update:modelValue event.