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.
data:{ message : "Hello World" } <input v-model="message" placeholder="edit me"> <p>Message is: { { message }}</p>
Message is: {{ message }}
value
Attributev-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.
data:{ message : "Hello World" } <input v-model="message" placeholder="edit me" value="Hi"> <p>Message is: { { message }}</p>
Message is: {{ message }}
As you can see, the value attribute on the input
element has no use if you are using v-model
.
v-model
also works on text area. But if you have New Line
entered in your textarea, the v-model
will simply convert it to space.
<textarea v-model="message" placeholder="edit me" value="Hi"> <p>Message is: { { message }}</p>
Message is: {{ message }}
Note that, in regular HTML, when we want to give an initial value to textarea we sometimes do the following -
<textarea>The initial message...</textarea>
And it will render like the following -
In Vue don't do it like this -
// The following is wrong <textarea>{ { message1 }}</textarea> <p> Message : { { message1 }}</p> data:{ message1:"The initial message..." }
Message : {{ message1 }}
As you can see, when you type in the text area, the value is not updating automatically. Well it won't. You should use v-model
isntead.
data:{ checked : false } <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{ { checked }}</label>
If you want the checkbox to be initially selected, just set the checked
to true.
data:{ checked : true } <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{ { checked }}</label>
Following is an example of multiple checkbox -
<div id='example-3'> <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> </div> new Vue({ el: '#example-3', data: { checkedNames: [] } });
For multiple checkbox the property in all the checkbox v-model should be same, and the property should be declared as an array. You should provide unique value to each checkbox.
Same as multiple checkbox, you can use the same for Radio button. Except you should decalre the property as a string, not an array, as only one value at a time can be stored -
<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> data:{ picked : "Two" }
For select element, v-model should be in the select element, not on the option element.
<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. In iOS, the behaviour is unpredictable, it won't allow user to select the first item from the select box. Weird.
Multiple select -
<select v-model="selected" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: { { selected }}</span> data:{ selected : [] }
You can provide the value attribute in the option
if your value is different than the text.
Here is an example of v-model
along 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' } ] } });
The above examples, except for the last example, uses static string as thier values. You can bind a dynamic property of vue instance to the value.
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" > <p>toggle : {{ toggle }}</p> data:{ toggle : 'yes' } // when checked: vm.toggle === 'yes' // when unchecked: vm.toggle === 'no'
toggle : {{ toggle }}
Here, true-value
and false-value
is attributes comes with Vue. true-value
is used to specify the value when the checkbox will be selected. And false-value
is the value that will be assigned to toggle
when it is not selected. Note that in the above example, we have assigned the value 'yes' to toggle
inside the data object. And this value is the same as true-value
's value. It means initially the checkbox will be selected.
Browsers don’t include unchecked boxes in form submissions. To guarantee that one of two values is submitted in a form (e.g. “yes” or “no”), use radio inputs instead.
An example of dynamic value binding would be as the following -
<input type="radio" v-model="pick" v-bind:value="a"> // when checked: vm.pick === vm.a
You can even bind an object as the value of the option
element.
<select v-model="selected"> <option v-bind:value="{ number: 123 }">123 </select> // when selected: typeof vm.selected // => 'object' vm.selected.number // => 123
By default, v-model syncs the input with the data after each input event. You can add the lazy modifier to instead sync after change events. In this case the vue property will be updated when the input element loses it's focus.
<input v-model.lazy="msg" ><br> Message : {{ msg }}
If you want user input to be automatically typecast as a number, you can add the number modifier to your v-model managed inputs. Note that you must need type="number"
on the input element otherwise this modifier have no effect.
<input v-model.number="age"> Number : { { age }}
This is often useful, because even with type="number", the value of HTML input elements always returns a string.
Now the msg
will contain trimmed data.