You can use the v-model
directive to create two-way data bindings on form input and textarea elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical, v-model
is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
v-model
will ignore the initial value
, checked
or selected
attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the data
option of your component.
For languages that require an IME (Chinese, Japanese, Korean etc.), you’ll notice that v-model
doesn’t get updated during IME composition. If you want to cater for these updates as well, use input
event instead.
<input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
<span>Multiline message is:</span> <p style="white-space: pre">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
Interpolation on textareas (<textarea>{{text}}</textarea>
) won't work. Use v-model
instead.
Single checkbox, boolean value:
<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label>
Multiple checkboxes, bound to the same Array:
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span>
new Vue({ el: '...', data: { checkedNames: [] } })
<input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span>
Single select:
<select v-model="selected"> <option disabled value="">Please select one</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span>
new Vue({ el: '...', data: { selected: '' } })
If the initial value of your v-model
expression does not match any of the options, the <select>
element will render in an “unselected” state. On iOS this will cause the user not being able to select the first item because iOS does not fire a change event in this case. It is therefore recommended to provide a disabled option with an empty value, as demonstrated in the example above.
Multiple select (bound to Array):
<select v-model="selected" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span>
Dynamic options rendered with v-for
:
<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span>
new Vue({ el: '...', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] } })
For radio, checkbox and select options, the v-model
binding values are usually static strings (or booleans for checkbox):
<!-- `picked` is a string "a" when checked --> <input type="radio" v-model="picked" value="a"> <!-- `toggle` is either true or false --> <input type="checkbox" v-model="toggle"> <!-- `selected` is a string "abc" when selected --> <select v-model="selected"> <option value="abc">ABC</option> </select>
But sometimes we may want to bind the value to a dynamic property on the Vue instance. We can use v-bind
to achieve that. In addition, using v-bind
allows us to bind the input value to non-string values.
<input type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value="b" >
// when checked: vm.toggle === vm.a // when unchecked: vm.toggle === vm.b
<input type="radio" v-model="pick" v-bind:value="a">
// when checked: vm.pick === vm.a
<select v-model="selected"> <!-- inline object literal --> <option v-bind:value="{ number: 123 }">123</option> </select>
// when selected: typeof vm.selected // -> 'object' vm.selected.number // -> 123
.lazy
By default, v-model
syncs the input with the data after each input
event (with the exception of IME composition as stated above). You can add the lazy
modifier to instead sync after change
events:
<!-- synced after "change" instead of "input" --> <input v-model.lazy="msg" >
.number
If you want user input to be automatically typecast as a number, you can add the number
modifier to your v-model
managed inputs:
<input v-model.number="age" type="number">
This is often useful, because even with type="number"
, the value of HTML input elements always returns a string.
.trim
If you want user input to be trimmed automatically, you can add the trim
modifier to your v-model
managed inputs:
<input v-model.trim="msg">
v-model
with ComponentsIf you’re not yet familiar with Vue’s components, just skip this for now.
HTML’s built-in input types won’t always meet your needs. Fortunately, Vue components allow you to build reusable inputs with completely customized behavior. These inputs even work with v-model
! To learn more, read about custom inputs in the Components guide.
© 2013–2017 Evan You, Vue.js contributors
Licensed under the MIT License.
https://vuejs.org/v2/guide/forms.html