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

v-model illustration for: 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:

				
					
&lt;h2&gt;My deepest, darkest question: {{existentialQuestion}}&lt;/h2&gt;

&lt;input v-model="existentialQuestion"/&gt;

				
			

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

				
					
&lt;p&gt;You have decided this statement is {{statementIsTrue}}&lt;/p&gt;

&lt;label&gt;

  &lt;input type="checkbox" v-model="statementIsTrue"/&gt;

  Is this statement true?

&lt;/label&gt;

				
			

…and try it live:

[codepen alligatorio abNYvxd]

Multiple Checkbox Example

The component data…

				
					
data() {

  return {

    namesThatRhyme: []  

  };

}

				
			

…and the template

				
					
&lt;p&gt;A list of names that rhyme: {{namesThatRhyme.join(', ')}}&lt;/p&gt;

&lt;label&gt;

  &lt;input type="checkbox" value="Daniel" v-model="namesThatRhyme"/&gt;

  Daniel

&lt;/label&gt;

&lt;label&gt;

  &lt;input type="checkbox" value="Nathaniel" v-model="namesThatRhyme"/&gt;

  Nathaniel

&lt;/label&gt;

&lt;label&gt;

  &lt;input type="checkbox" value="Hubert" v-model="namesThatRhyme"/&gt;

  Hubert

&lt;/label&gt;

				
			

…and the demo:

[codepen alligatorio NWNYGZE]

Radio Button Example

The component data…

				
					
  data() {

    return {

      howAreYouFeeling: "great"

    };

  }

				
			

…and the template

				
					
&lt;p&gt;How are you feeling today?&lt;/p&gt;

  &lt;label&gt;

    &lt;input type="radio" value="great" v-model="howAreYouFeeling" /&gt;

    great

  &lt;/label&gt;

  &lt;label&gt;

    &lt;input type="radio" value="wonderful" v-model="howAreYouFeeling" /&gt;

    wonderful

  &lt;/label&gt;

  &lt;label&gt;

    &lt;input type="radio" value="fantastic" v-model="howAreYouFeeling" /&gt;

    fantastic

  &lt;/label&gt;

  &lt;p&gt;I am also feeling &lt;em&gt;{{howAreYouFeeling}}&lt;/em&gt; today.&lt;/p&gt;

				
			

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.