anirbmuk / toggle-button-vue
A toggle-button component using Vue3
This blog post aims to create a simple Toggle-Button component with Vue3, which can also be integrated with a form, via v-model.
Sometimes it is important to create these UI components on your own, instead of relying on heavier UI libraries. When you do this, you get to learn a few more intricate stuff, which you may ignore while using ready-made solutions, and also, you make it light-weight by excluding features you may not even need.
The ToggleButton Component
Props:
-
options
(array) -
modelValue
(string)
defineProps({ modelValue: { type: String, default: '' }, options: { type: Array as PropType<KeyValue<string>[]>, required: true } })
Emits:
-
update:model-value
(string)
defineEmits<{ (e: 'update:model-value', value: string): void }>()
Let's talk about the props.
The options
array is a list of key-value objects, which are displayed as buttons.
<template v-for="option of options" :key="option.value"> <button type="button" :class="{ selected: modelValue === option.value }" @click="$emit('update:model-value', option.value)" > {{ option.label }} </button> </template>
The modelValue
prop is an interesting one. It should be named modelValue
(case-sensitive), if you want this component to have a data-binding. When a custom component has this prop, and it is bound to a v-model
, the value flows into this component and is applied to the underlying model.
If you want the component to have a 2-way data-binding, you also need to define an emit called update:model-value
(again, case-sensitive). You write your logic to emit this event with the new value, every time a new button is clicked.
... @click="$emit('update:model-value', option.value)" ...
Now that your component is ready for 2-way binding, you can use it in your application:
<ToggleButton :options="options" v-model="selected" /> ... const options = [ { label: 'Male', value: 'M' }, { label: 'Female', value: 'F' }, { label: 'Diverse', value: 'D' } ] satisfies KeyValue<string>[] const selected = ref<string>('F')
That's all folks. Refer to the GitHub repo for the complete code!
Top comments (0)