← Back to all tutorials

Two-Way Data Binding

Use v-model for two-way data binding — sync form inputs with data properties so changes flow in both directions.

Two-Way Data Binding

So far, data flows from the Vue instance to the template (one-way). With v-model, data flows in both directions — when you type into an input, the data updates; when the data changes, the input updates. This is two-way data binding.

v-model on Text Inputs

<div id="app">
    <label>Name:</label>
    <input type="text" v-model="name">
    <p>Your name is: {{ name }}</p>
</div>

<script>
new Vue({
    el: '#app',
    data: {
        name: ''
    }
});
</script>

Typing in the input updates name in real time, and the paragraph below reflects the change instantly. If you change name programmatically, the input also updates.

How v-model Works

<!-- v-model is syntactic sugar for: -->
<input :value="name" @input="name = $event.target.value">

<!-- v-model combines both into: -->
<input v-model="name">

v-model on Different Inputs

Input TypeUsageData Type
Text<input v-model="text">String
Textarea<textarea v-model="text">String
Number<input v-model.number="age">Number
Checkbox<input type="checkbox" v-model="checked">Boolean
Radio<input type="radio" v-model="picked">String
Select<select v-model="selected">String

v-model Modifiers

ModifierPurpose
.lazySync on change event instead of input (updates on blur)
.numberAutomatically convert the value to a number
.trimTrim whitespace from the input
<input v-model.lazy="name">       <!-- Updates on blur, not keystroke -->
<input v-model.number="age">      <!-- Converts to number -->
<input v-model.trim="username">   <!-- Trims whitespace -->

Key Takeaways

  • v-model creates two-way binding between form inputs and data properties
  • It is syntactic sugar for :value + @input combined
  • Works with text, textarea, checkbox, radio, and select inputs
  • Use .number, .trim, and .lazy modifiers for common transformations