Using v-model for Two-Way Binding in Vue.js

Joshua Bemenderfer

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"/>

And just like that, your input value will be Am I truly an alligator?, and the existentialQuestion property (and the h2 element) will update whenever you type in the input.

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>

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>

Radio Button Example

The component data…

data() {
  return {
    statementIsTrue: 'Yes'
  }
}

…and the template

<p>You have decided this statement is </p>
Is this statement true? {{statementIsTrue}}.
<label>
  <input type="radio" value="Yes" v-model="statementIsTrue"/>
  Yes, it is true.
</label>
<label>
  <input type="radio" value="No" v-model="statementIsTrue"/>
  No, not at all.
</label>

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.
✖ Clear

🕵 Search Results

🔎 Searching...