Mastering Custom Vue.js Inputs: Build Radio Buttons and Checkboxes with v-model
This guide explains how to create reusable custom input components in Vue.js, covering the fundamentals of v-model, implementing custom radio buttons and checkboxes, handling single and multiple selections, and providing complete code examples for building robust form controls.
Introduction
Component‑based libraries like Vue make it easy to create reusable UI elements that behave consistently across applications. Custom input components—such as radios, checkboxes, and text fields—can encapsulate design, validation, and helper text while supporting Vue's v-model directive for two‑way data binding.
How v-model Works
Vue’s v-model is syntactic sugar for binding a value and listening to an input event. For native inputs it translates to :value="varName" @input="e => varName = e.target.value". The same principle applies to custom components, but the component must emit the bound event and accept a prop for the value.
Custom Radio Buttons
Radio buttons share a model value; the component checks whether its value matches the model. The implementation uses a computed property to determine the checked state and emits a change event with the new value.
<template>
<label>
<input type="radio" :checked="shouldBeChecked" :value="value" @change="updateInput" />
{{ label }}
</label>
</template>
<script>
export default {
model: { prop: 'modelValue', event: 'change' },
props: { value: String, label: String },
computed: {
shouldBeChecked() { return this.modelValue === this.value; }
},
methods: {
updateInput(event) { this.$emit('change', event.target.value); }
}
};
</script>Custom Checkboxes
Checkboxes can operate in two modes: a single boolean toggle or a multiple‑selection array. The component determines the mode by checking if the bound model is an array. It uses true-value and false-value props for custom true/false representations.
<template>
<label>
<input type="checkbox" :checked="shouldBeChecked" :value="value" @change="updateInput" />
{{ label }}
</label>
</template>
<script>
export default {
model: { prop: 'modelValue', event: 'change' },
props: {
value: String,
label: String,
trueValue: { default: true },
falseValue: { default: false }
},
computed: {
shouldBeChecked() {
if (Array.isArray(this.modelValue)) {
return this.modelValue.includes(this.value);
}
return this.modelValue === this.trueValue;
}
},
methods: {
updateInput(event) {
const isChecked = event.target.checked;
if (Array.isArray(this.modelValue)) {
const newValue = [...this.modelValue];
if (isChecked) newValue.push(this.value);
else {
const idx = newValue.indexOf(this.value);
if (idx > -1) newValue.splice(idx, 1);
}
this.$emit('change', newValue);
} else {
this.$emit('change', isChecked ? this.trueValue : this.falseValue);
}
}
}
};
</script>Putting It All Together
By defining model, props, computed properties, and methods as shown, you can create fully functional custom radio and checkbox components that integrate seamlessly with v-model. These components can be used in single‑file component syntax for clearer project structure.
Further Reading
Awesome‑Vue’s Component Sets – a curated list of UI libraries with checkbox and radio examples.
Vue Curated – an extensive collection of Vue resources and tutorials.
Vue Component Guide – official documentation for building Vue components.
Vue API Documentation – detailed reference for Vue’s core features.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD.com Experience Design Center
Professional, creative, passionate about design. The JD.com User Experience Design Department is committed to creating better e-commerce shopping experiences.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
