Vue two way data-binding in custom checkbox
Danilo Miranda
Posted on June 8, 2021
When writing vue application, you'll probably come across a situation where you need to write custom input components, and therefore leverage the two way data binding functionality.
A simple custom text input is easiy achievable and it's documented here
But there's a different approach to achieve the same two way data binding functionality in custom checkbox components.
Creating the custom checkbox component
Let's start creating our component. It will be as simple as just rendering the checkbox and a label can be set through props.
Checkbox.vue
<template>
<label>
<input type="checkbox" :value="inputValue" v-model="model" />
<span>{{ label }}</span>
</label>
</template>
<script>
export default {
name: "Checkbox",
props: {
label: String,
value: Array,
inputValue: String,
},
computed: {
model: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
},
},
},
};
</script>
Now, take a look at this part:
<input type="checkbox" :value="inputValue" v-model="model" />
We are defining a checkbox input, and binding the value
attribute to our inputValue
, which will simply be used to determine the input's value for a form submission for example, just like you would do with normal html
<input type="checkbox" value="somoething" />
Now, v-model
is bound to a property called model
which is a computed property:
computed: {
model: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
},
},
},
The getter for this property will simply return value to v-model
and when the data has to be updated, through the setter, we emit the input event, to let the part of the application that's using this custom checkbox component, that the value has been updated.
It's important to note that the value
property was declared as being an array, since each time we mark a new checkbox, this checkbox value will be pushed to this array bound to v-model
property.
Using the component
Now that we have defined how our component will work, we can use it in an example and see if it wil work.
I'll just define a simple Vue component that will use this checkbox component we just created:
Home.vue
<template>
<div>
<Checkbox label="React" inputValue="react" v-model="selectedOptions" />
<Checkbox label="Vue" inputValue="vue" v-model="selectedOptions" />
<Checkbox label="Angular" inputValue="angular" v-model="selectedOptions" />
<br /><br /><br />
<ul>
<li v-for="(option, index) of selectedOptions" :key="index">
{{ option }}
</li>
</ul>
</div>
</template>
<script>
import Checkbox from "./Checkbox";
export default {
name: "Home",
props: {},
components: {
Checkbox,
},
data() {
return {
selectedOptions: [],
};
},
};
</script>
In this example, we have three checkboxes component in use, with three different value for each one of them: react, vue and angular
with their respective labels.
<Checkbox label="React" inputValue="react" v-model="selectedOptions" />
<Checkbox label="Vue" inputValue="vue" v-model="selectedOptions" />
<Checkbox label="Angular" inputValue="angular" v-model="selectedOptions" />
We are binding the v-model
property to selectedOptions
reactive data property of our home component, which wil be an array.
To make sure that we are updating this selectedOptions
each time a check or uncheck an input, I added a simple loop, to render each value in selectedOptions
array:
<ul>
<li v-for="(option, index) of selectedOptions" :key="index">
{{ option }}
</li>
</ul>
You can see a working example here in CodeSandbox:
Posted on June 8, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.