Introduction

The user action on the view is forwarded to the application with the “v-on:” directive, after processing the data to update the user interface, we forward the data from the application by interpolation or the v-bind directive. Each of the listed individual procedures represents data forwarding in one direction (“one-way binding”). However, data entry fields are specific, because they need forwarding of data in both directions (eng. “two-way binding”), therefore both directives are needed on the same element.
In the following example, the data from the form is passed to the data object with the “v-on:input” directive, while the data changed from the application itself updates the value in the HTML input with the “v-bind:value” directive.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div id="app" <input v-on:input="cuvarVrednosti = $event.target.value" v-bind:value="cuvarVrednosti"> </div> <script> new Vue({ el: '#app', data: { cuvarVrednosti: 'some text' } methods: { reset(){ cuvarVrednosti = ''; } } }) </script> |
Within Vue.js there is a directive that covers this process called “v-model”, with the use of which the code looks much simpler, so instead of:
|
1 |
<input v-on:input="cuvarVrednosti = $event.target.value" v-bind:value="cuvarVrednosti"> |
we use a clearer and simpler syntax:
|
1 |
<input v-model="cuvarVrednosti"> |
NOTE:
The “v-model” directive will ignore the initial value defined on some form element (selected and checked), because it considers the “data” property as the main source. Therefore, if we want to declare an initial value on a form element, we need to do it inside the “data” property or bind the value with the “v-bind” directive.
See the Pen Initial setting of input values by Web programming (@chos) on CodePen.
Syntax
The v-model directive can only be used with the following HTML elements input, select, and textarea.
a) Textbox
|
1 |
<input v-model="message" placeholder="edit me"> |
b) Textarea
|
1 |
<textarea v-model="message" placeholder="add multiple lines"></textarea> |
NOTE:
Interpolation with “textarea” element
<textarea>{{text}}</textarea> is not possible
c) Checkbox
Single checkbox
If there is only one chekcbox field “v-model” the directive will treat it as a boolean value, and will fire the typed value (in the example: value=”foo”), therefore the choice can be either “true” or “false”.
See the Pen v-model – single checkbox by Web programming (@chos) on CodePen.
Multiple checkboxes
If you have multiple checkboxes that share the same model, then those fields will populate an array with the values of all the checkboxes, so make sure the “data” property is defined as an array.
Example
See the Pen V-model checkbox by Web programming (@chos) on CodePen.
d) Radio input
|
1 |
<input type="radio" id="mika" value="Mika" v-model="izabranRadnik"> |
Example
See the Pen V-model – radio by Web programming (@chos) on CodePen.
e) Select
Example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<select v-model="izbor"> <option disabled value="">Izaberite jednu opciju</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Izabrali ste: {{ izbor }}</span> <script> new Vue({ el: '...', data: { izbor: '' } }) </script> |
Example
If multiple selection is defined, then the “data” property must be defined as a string:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<select v-model="izbor" multiple> <option>A</option> <option>B</option> <option>C</option> </select> <span>{{ izbor }}</span> <span>Selected: {{ izbor }}</span> <script> new Vue({ el: '#app', data: { izbor: [] } }) </script> |
Example
See the Pen v-model for select by Web Programming (@chos) on CodePen.
v-model modifiers
Modifiers are special keywords that affect the input in some way. There are three modifiers that can be used with this directive:
.trim
When using this modifier, any leading, trailing, or multiple whitespace in the input field will be stripped before the value is synced to the “data” property.
|
1 |
<input type="text" v-model.trim="name"> |
Example
See the Pen Trim modifier by Web programming (@chos) on CodePen.
.lazy
By default, the v-model is processed every time a “keypress” input event fires. If we do not want the input via the input element to be automatically synchronized with the “data” property for each entered character, but to be synchronized only after the input is finished (enter is pressed or we exit the focus in some other way), then we need to use the modifier .lazy
|
1 |
<input type="text" v-model.lazy="message"> |
.number
JavaScript treats the value entered through the “input” element of the “text” type as a “string”, so if we work with numbers, it is necessary to cast each input into “number”. It is this modifier that ensures that the input is always automatically converted to a number, which would be equivalent to calling the javascript function “parseInt()”.
Example
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div id="app"> <input v-model.number="a"> <p>Variable "b" is always 10 greater than the input and equals: {{ b }}</p> </div> <script type="text/javascript"> new Vue({ el: '#app', data: { a: 1, }, computed: { b: function () { return this.a + 10 } } } </script> |
If you didn’t use this modifier, you would get an illogical result. So, for example, if you entered a value of 5 for the variable “a”, the value of “b” would be 510, because javascript would perform a string concatenation instead of an addition operation.
NOTE:
If an input element with the defined type “number” is used, it is not necessary to use this modifier, because Vue.js automatically casts to number.
Dynamic value binding
Predefined values (string or boolean) are mostly used for radio buttons, checkboxes and selects, howeverthere may be a need to bind some dynamic value. In that case, we also use the “v-bind” directive, which allows us to bind the input to “non-string” values as well.
a) radio buttons
|
1 2 3 |
<input type="radio" v-model="pick" v-bind:value="a"> // when checked: vm.pick === vm.a |
Example
See the Pen Dynamic radio binding by Web programming (@chos) on CodePen.
b) select
|
1 2 3 4 5 6 7 8 |
<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 |
