Table of Contents
URL: https://www.progressiverobot.com/vuejs-v-model-two-way-binding/
Vue's two-way binding system takes one of the trickiest parts of developing a web application, user input synchronization, and makes it dead simple with v-model. The v-model directive updates the template whenever the model changes and updates data model whenever the template changes.
Two-way binding is a powerful feature that, if used properly, can significantly speed up your development process. It reduces the complexity of keeping user input consistent with the application data model.
In Vue, two-way binding is accomplished using the <^>v-model<^> directive.
Binding to Text Input Elements
To bind the value of an input element to a property of your component's data, use v-model="dataProperty" like so.
Here's the component's data method:
data() {
return {
existentialQuestion: 'Am I truly an alligator?'
};
}
And the template:
<h2>My deepest, darkest question: {{existentialQuestion}}</h2>
<input v-model="existentialQuestion"/>
Here it is in a live demo:
[codepen alligatorio poyLjqY]
Notice the input value starts out as Am I truly an alligator?, but when you change the input, the <^>existentialQuestion<^> property (and the h2 element) will update in real time.
Binding to Checkboxes and Radio Buttons
Checkboxes and radio buttons work pretty much like input elements. A checkbox binding will either be true or false, while a radio button binding will be whatever the contents of its <^>value<^> property is.
Additionally, a set of checkboxes can be bound to a single array, which will put the contents of their <^>value<^> property in the array if checked.
Single Checkbox Example
The component data…
data() {
return {
statementIsTrue: true
};
}
…and the template
<p>You have decided this statement is {{statementIsTrue}}</p>
<label>
<input type="checkbox" v-model="statementIsTrue"/>
Is this statement true?
</label>
…and try it live:
[codepen alligatorio abNYvxd]
Multiple Checkbox Example
The component data…
data() {
return {
namesThatRhyme: []
};
}
…and the template
<p>A list of names that rhyme: {{namesThatRhyme.join(', ')}}</p>
<label>
<input type="checkbox" value="Daniel" v-model="namesThatRhyme"/>
Daniel
</label>
<label>
<input type="checkbox" value="Nathaniel" v-model="namesThatRhyme"/>
Nathaniel
</label>
<label>
<input type="checkbox" value="Hubert" v-model="namesThatRhyme"/>
Hubert
</label>
…and the demo:
[codepen alligatorio NWNYGZE]
Radio Button Example
The component data…
data() {
return {
howAreYouFeeling: "great"
};
}
…and the template
<p>How are you feeling today?</p>
<label>
<input type="radio" value="great" v-model="howAreYouFeeling" />
great
</label>
<label>
<input type="radio" value="wonderful" v-model="howAreYouFeeling" />
wonderful
</label>
<label>
<input type="radio" value="fantastic" v-model="howAreYouFeeling" />
fantastic
</label>
<p>I am also feeling <em>{{howAreYouFeeling}}</em> today.</p>
Here it is in a demo:
[codepen alligatorio gOreaVe]
Notes
- By default, v-model is evaluated every time the <^>input<^> event is fired (ie. on keypress or paste.) If you'd rather wait until the user has finished inputting and unfocused the field, you can use the <^>v-model.lazy<^> modifier to have v-model listen to the <^>change<^> event instead.
- If you'd like to cast user input to a number instead of a string, add the <^>v-model.number<^> modifier. You'll have to handle casting to other types yourself.
- The <^>v-model.trim<^> modifier will strip and leading or trailing whitespace from the bound string. This (obviously) cannot be used in conjunction with <^>v-model.number<^>.
- While <^>v-model="dataProperty"<^> seems like magic at first glance, it's actually just short-hand for
:value="dataProperty" @input="dataProperty = $event.target.value". As such, you can easily implement v-model support for your own components.