In this tutorial we're going to learn how to use v-model
attribute with custom components to return the values of the custom component back to the parent component.
What Is v-model?
The v-model
attribute is a way of creating a two way binding between the user input and the vuejs component. This will automatically pick up changes and store this value in the data properties of the component.
This will be commonly used on a form input to record the user input.
<input v-model="message" placeholder="edit me">
The component will then have a data property of message to record the same value the user entered.
Why Use v-model On Custom Component
What about in the situation where you want to create some generic form components to keep things consistent. For example maybe you want to make sure that all input boxes share the same HTML structure and functionality, it makes sense to create a custom component where you can to import on every page.
Therefore you might create a component that had html like this.
<div>
<label>{{ label }}</label>
<p>
<input
class="input"
type="text"
:id="id"
:placeholder="label"
:value="value"
:required="required">
</p>
</div>
You'll notice we've added extra properties for id, placeholder, value and required where we can pass in props to customise the text input.
This component can be reused on any form in your application by importing the component and using it as simple as
<form-text label="Name" :required="true" id="name" />
But when you include this in a parent form you need a way of assigning a data property to it. To do this we need to use the v-model
property, like this.
<form-text v-model="name" label="Name" :required="true" id="name" />
Then we can make this custom component reactive and change the name
data property. At the moment this v-model
won't do anything we need to change the component slightly.
How To Use v-model On A Custom Component
In this section we'll look at what the v-model
property does and how we can change the custom component to make this work.
The internal workings of v-model
is quite simple, it will pass a value prop into the component and then assign an event on the input event to change the value based on the user input.
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
Therefore we can use this same internal workings on our own component. But instead of changing the value we can emit an event to change the input.
We can do this by adding a method on the input event
v-on:input="updateValue($event.target.value)">
Then using this method emit
the input.
methods: {
updateValue: function (value) {
this.$emit('input', value)
}
}
Finally add a value prop.
props: {
value: {
type: String
}
}
Now we can use the v-model
and it will change the data property of the parent component like this
<form-text v-model="name" label="Name" :required="true" id="name" />
Full Custom Text Input Component
<template>
<div>
<label>{{ label }}</label>
<p>
<input
class="input"
type="text"
:id="id"
:placeholder="label"
:value="value"
:required="required"
v-on:input="updateValue($event.target.value)">
</p>
</div>
</template>
<script>
export default {
props: {
id: {
type: String
},
label: {
type: String,
required: true
},
value: {
type: String
},
required: {
type: Boolean,
default: false
}
},
methods: {
updateValue: function (value) {
this.$emit('input', value)
}
}
}
</script>
Further Reading
For further reading on using v-model
on components you can view the VueJS documentation