In this article, we’ll look at how to bind data in various ways and automatically modify inputs.
Value Bindings
v-model
bind values usually as static strings, or booleans for a checkbox.
For example, for checkbox, we can bind it to a string as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
selected: undefined
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
foo
<input type="radio" v-model="selected" value="foo" />
<br />
bar
<input type="radio" v-model="selected" value="bar" />
<br />
<span>Selected: {{ selected }}</span>
</div> <script src="src/index.js"></script>
</body>
</html>
Checkboxes are bound to a boolean value:
<input type="checkbox" v-model="toggle">
Select are bound to the selected string set in the value
attribute:
<select v-model="selected">
<option value="foo">Foo</option>
</select>
Checkbox
We can change the true and false value of a checkbox with the true-value
and false-value
attributes as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
selected: undefined
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
Toggle
<input
type="checkbox"
v-model="selected"
true-value="yes"
false-value="no"
/>
<br />
<span>Selected: {{ selected }}</span>
</div> <script src="src/index.js"></script>
</body>
</html>
Then we get yes
when we checked the checkbox and no
otherwise.
true-value
and false-value
don’t affect the input’s value
attribute because browsers don’t include unchecked boxes in form submissions.
We should use radio inputs to guarantee at least one item is selected.
Radio Buttons
We can bind the value
attribute to the selected value with v-bind:value
.
For example, we can write the following:
src/index.js
:
new Vue({
el: "#app",
data: {
pick: "",
foo: "foo",
bar: "bar"
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
Foo
<input type="radio" v-model="pick" v-bind:value="foo" />
<br />
Bar
<input type="radio" v-model="pick" v-bind:value="bar" />
<br />
<p>Selected: {{ pick }}</p>
</div> <script src="src/index.js"></script>
</body>
</html>
Then v-bind:value=”foo”
renders as value='foo'
and v-bind:value=”bar”
is rendered as value='bar'
.
When we pick a value, we get foo
or bar
depending on which radio button is clicked.
Select Options
We can bind a value to an object as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
selected: undefined
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<select v-model="selected">
<option v-bind:value="{ number: 123 }">123</option>
<option v-bind:value="{ number: 456 }">456</option>
</select>
<br />
<p>Selected: {{ selected }}</p>
</div> <script src="src/index.js"></script>
</body>
</html>
Then we get either { number: 123 }
or { number: 456 }
displayed depending on what’s selected.
If we want to display the value of the number
property, then we have to write the following:
src/index.js
:
new Vue({
el: "#app",
data: {
selected: {}
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<select v-model="selected">
<option v-bind:value="{ number: 123 }">123</option>
<option v-bind:value="{ number: 456 }">456</option>
</select>
<br />
<p>Selected: {{ selected.number }}</p>
</div> <script src="src/index.js"></script>
</body>
</html>
Since setting the initial value to undefined
will give us an error and the app won’t run.
Modifiers
Vue comes with a few modifiers for v-model
.
.lazy
We can use v-model.lazy
to sync data on change
events rather than input
events. This means that changes are only synced when the input it out of focus.
For example, we can use it as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
msg: ""
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<input v-model.lazy="msg" />
<br />
<p>Value: {{ msg }}</p>
</div> <script src="src/index.js"></script>
</body>
</html>
When we move out cursor out of the input, then we get the input value displayed.
.number
The number
modifier will convert whatever’s entered into a number. This is useful because input with type='number'
still returns a string.
For example, we can use it as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
age: 0
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<input v-model.number="age" type="number" />
<br />
<p>Age: {{ age }}</p>
</div> <script src="src/index.js"></script>
</body>
</html>
.trim
We can trim whitespace automatically with the .trim
modifier. To use it, we can write the following:
src/index.js
:
new Vue({
el: "#app",
data: {
msg: ""
}
});
index.html
:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<input v-model.trim="msg" type="text" />
<br />
<p>Value: "{{ msg }}"</p>
</div> <script src="src/index.js"></script>
</body>
</html>
Then when we type in something with starting and ending whitespaces, they won’t show up.
Example " a b c " will become "a b c" .