DEV Community

Cover image for Vue3 Tailwind CSS Form Components Part III - Reusable BaseCheckbox Component
ScriptMint
ScriptMint

Posted on

Vue3 Tailwind CSS Form Components Part III - Reusable BaseCheckbox Component

This is third part of Vue3 Tailwind Form Components Series

Form Components are very important for any Web Application. Think about a project without proper Form Components with multiple forms in it. What if you need to change design of your checkbox input or you wish to add extra functionality into checkbox input? I did the same mistake in 2018 when using Vue2 and still my project is not easy to maintain.

Live Demo: https://scriptmint-solution.github.io/vue3-tailwind-form-components/

GitHub Repository: https://github.com/scriptmint-solution/vue3-tailwind-form-components

Do check our Advanced Featured Admin Panel at Vana Admin built with Laravel, Vue.js 3 & Tailwind CSS 3 with tons of inbuilt features to quickly build your next project.

BaseCheckbox

Lets start with this Component:

Here is the Code, we would like to get a Custom Checkbox Component.

<BaseCheckbox id="name" name="name" label="Sample Checkbox" />
Enter fullscreen mode Exit fullscreen mode

We will start with a very basic checkbox component. Create a BaseCheckbox.vue file inside your components directory.

<template>
    <div>
        <input
              type="checkbox"
              class="h-4 w-4 focus:ring-0 cursor-pointer rounded"
        />
        <label class="ml-2 block text-sm text-gray-900 cursor-pointer">
              label goes here!
        </label>
    </div>
</template>

<script>
export default {
    name: 'BaseCheckbox',
    inheritAttrs: false
}
</script>

<script setup>
</script>
Enter fullscreen mode Exit fullscreen mode

We have only applied some css classes to make it look better. Lets add some props now. Also note that we have set inheriAttrs property to false, as we wish to bind the attributes of BaseCheckbox to the input field (Not with the root element).

<script setup>
const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    }
})
</script>
Enter fullscreen mode Exit fullscreen mode

In Vue3, you can pass v-model attribute in your component and it will be available as modelValue inside your component. Also, we need to bind this modelValue to the value attribute of the input field.

Next, we need to emit the value everytime whenever user check or uncheck it. To do so, we will make:

<input 
    v-bind="$attrs"
    :checked="modelValue"
    @change="updateInput"
    type="checkbox"
    rows="3" class="w-full shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
/>
...
...

const emit = defineEmits(['update:modelValue'])

const updateInput = ($event) => {
    emit('update:modelValue', $event.target.checked)
}
Enter fullscreen mode Exit fullscreen mode

Here, we bind the attributes to the the field which emits the value of the checkbox field and make it available to the BaseCheckbox component v-model attribute via two way binding.

Unlike BaseInput or BaseTextarea component, here we emit an event on change event & emit the checked value of the element.

That's all. You have successfully created your BaseCheckbox component and use it anywhere in the project.

You can add id attribute to your checkbox component and to the label component so that user when click on the label, can check or uncheck the component.

Here is the final code for this BaseCheckbox component:

<template>
    <div>
        <input
            v-bind="$attrs"
            :checked="modelValue"
            @change="updateInput"
            type="checkbox"
            class="h-4 w-4 focus:ring-0 cursor-pointer rounded"
        />
        <label :for="$attrs.id" class="ml-2 block text-sm text-gray-900 cursor-pointer">
            {{label}}
        </label>
    </div>
</template>

<script>
export default {
    name: 'BaseCheckbox',
    inheritAttrs: false
}
</script>

<script setup>
const emit = defineEmits(['update:modelValue'])

const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    modelValue: {
        type: Boolean,
        default: false
    }
})

const updateInput = ($event) => {
    emit('update:modelValue', $event.target.checked)
}
</script>
Enter fullscreen mode Exit fullscreen mode

Check all the source code in the GitHub repo at https://github.com/scriptmint-solution/vue3-tailwind-form-components

Discussion (0)