I have a form and bind an input using v-model:
<input type="text" name="name" v-model="form.name">
Now I want to extract the input and make it it's own component, how do you then bind the values of the child component to the parents object form.name
?
Adding v-model to Custom Components To let our component support v-model two-way binding, the component needs to accept a value prop and emit an input event. To support v-model , the component accepts a value prop and emits an input event. With that, the custom component supports v-model two-way binding.
The V-model is a graphical representation of a systems development lifecycle. It is used to produce rigorous development lifecycle models and project management models.
Parent To Child Communication In Vue. To move data from a parent component to a child component in Vue we use something called props. ReactJS also uses a similar convention for sharing data. Props is short for “properties” and is referring to properties set from outside, such as from the parent component.
lazy. By default, v-model syncs with the state of the Vue instance (data properties) on every input event - which means every single time the value of our input changes. The . lazy modifier changes our v-model so it only syncs after change events.
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:
value
prop for the componentget
method for the computed property which returns the value
prop's valueset
method for the computed property which emits an input
event with the updated value whenever the property changesHere'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.
Per the documentation, there are breaking changes to the v-model implementation in Vue 3:
value
-> modelValue
input
-> update:modelValue
Specify a :value
prop and an @input
event in the child component, then you can use v-model
syntax in the parent component.
MyInput.vue
<template> <input :value="value" @input="$emit('input', $event.target.value)" /> </template> <script> export default { props: ['value'] }; </script>
Screen.vue
<template> <my-input v-model="name" /> </template> <script> import MyInput from './MyInput.vue'; export default { components: { MyInput }, data: () => ({ name: '' }) }; </script>
MyInput.vue
<template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template> <script> export default { props: ['modelValue'] }; </script>
Screen.vue
<template> <my-input v-model="name" /> </template> <script> import MyInput from './MyInput.vue'; export default { components: { MyInput }, data: () => ({ name: '' }) }; </script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With