Two-Way Data Binding in Vue With v-model
Two way data binding is a powerful pattern for building JavaScript forms with Vue. For example,
suppose you have an input
element and a JavaScript variable value
.
Two way data binding means:
- When the user types in the
input
,value
gets updated to match the value ininput
. - When you update
value
, theinput
element's content updates to matchvalue
.
Vue supports two way data binding via the v-model
property. In the below example, if you type in the input, Vue will display your changes in the h1
element. Also, if you update value
by clicking the "Reset" button, Vue will display the new value
in the input
and h1
elements.
const app = new Vue({
data: () => ({ value: 'Hello, World' }),
template: `
<div id="rendered-content">
<h1>{{value}}</h1>
<div>
<input v-model="value"></input>
</div>
<button v-on:click="value = 'Hello, World'">
Reset
</button>
</div>
`
});
With Checkboxes and Dropdowns
The v-model
property works seamlessly with other native inputs. If
you have an input of type 'checkbox', v-model
will store a boolean:
const app = new Vue({
data: () => ({ value: false }),
template: `
<div id="rendered-content">
<h1>{{value}}</h1>
<div>
<input type="checkbox" v-model="value"></input>
</div>
<button v-on:click="value = false">
Reset
</button>
</div>
`
});
Here's a live example of using v-model
with checkboxes.
If you attach v-model
to a select
element, Vue will bind to the
selected option's value
.
const app = new Vue({
data: () => ({ value: 'B' }),
template: `
<div id="rendered-content">
<h1>{{value}}</h1>
<div>
<select v-model="value">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</div>
<button v-on:click="value = 'B'">
Reset
</button>
</div>
`
});
Custom Inputs
Under the hood, v-model
builds on 2 other Vue properties:
You can use v-model
with a custom Vue component by accepting a prop named 'value' and emitting an event named 'input'. For example, the below custom component is a fake select using div
elements. Clicking on a div
selects it.
Vue.component('my-select', {
// `v-model` passes the 'value' as a prop...
props: ['value'],
methods: {
set: function(v) {
// And listens to the 'input' event for changes
this.$emit('input', v);
}
},
template: `
<div>
<div v-for="v in ['A', 'B', 'C']" v-on:click="set(v)">
{{v}}
<span v-if="v === value">[x]</span>
</div>
</div>
`
});
const app = new Vue({
data: () => ({ value: 'B' }),
template: `
<div id="rendered-content">
<h1>{{value}}</h1>
<div>
<my-select v-model="value"></my-select>
</div>
<button v-on:click="value = 'B'">
Reset
</button>
</div>
`
});