As stated in the documentation,
v-model is syntactic sugar for:
<input v-bind:value="something" v-on:input="something = $event.target.value">
To implement the v-model directive for a custom component:
- specify a
valueprop for the component - make a computed property with a computed setter for the inner value (since you should not modify the value of a prop from within a component)
- define a
getmethod for the computed property which returns thevalueprop’s value - define a
setmethod for the computed property which emits aninputevent with the updated value whenever the property changes
Here’s a simple example:
Vue.component('my-input', {
template: `
<div>
My Input:
<input v-model="inputVal">
</div>
`,
props: ['value'],
computed: {
inputVal: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
}
})
new Vue({
el: '#app',
data() {
return {
foo: 'bar'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<!-- using v-model... -->
<my-input v-model="foo"></my-input>
<!-- is the same as this... -->
<my-input :value="foo" @input="foo = $event"></my-input>
{{ foo }}
</div>
Thanks to @kthornbloom for spotting an issue with the previous implementation.
Breaking changes in Vue 3
Per the documentation, there are breaking changes to the v-model implementation in Vue 3:
value->modelValueinput->update:modelValue