Creating a Simple Tags Component in Vue

Tag inputs in a form are quire popular. A good tag input gives a nice surface to handle separate values that belong to the same “namespace”. Let’s see how to build a very simple tag input with Vue.

The Component

What is very important with a unique form component, that it needs to work like it would be a simple input. It means it needs to handle v-model for example, or emit events, handle the value property and so on. So, first, let’s take a look at the whole component and then move on the little details.

<template>
    <div>
        <div class="input-wrapper">
            <input type="text" v-model.trim="tag" @keypress.prevent.stop.enter="addTag">
            <button @click.prevent.stop="addTag">Add</button>
        </div>

        <ul class="tags">
            <li class="tag" v-for="(tag, index) in tags" :key="index">
                <span>{{ tag }}</span>
                <span @click="tags.splice(index, 1)">&times;</span>
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        props: {
            value: {
                type: Array,
                default: () => []
            }
        },

        watch: {
            tags(n, o) {
                this.$emit('input', n);
            }
        },

        data() {
            return {
                tag: '',
                tags: this.value || []
            };
        },

        methods: {
            addTag() {
                if (this.tag && ! this.tags.includes(this.tag)) {
                    this.tags.push(this.tag);
                    this.tag = '';
                }
            }
        }
    }
</script>

So, here is the whole component, that can be registered globally with the Vue.component(‘tags’, ….) code. Now, let’s move on the little details.

Handling the Data

First of all, let’s clear why do we use the value property. Then we bind a value to the component with v-model or the value attribute, the given data will be accessible by the value property. If there is any given data, then we use is as a default, otherwise, the tags will be an empty array.

Also, we can see, there is a watcher for the tags data property. It’s important to understand, that the v-model updates the data in the outer scope only if the input event is emitted from the component – like it would be a normal input. So when the array of tags changes in the inner scope, we emit the event that mirrors the change to the outer scope.

You can see, in the addTag method empty and existing tags are blocked, cannot be added to the existing tags. If you accept the same tags multiple times, then remove the this.tags.includes(this.tag) from the check.

Summary

As you can see, it’s very simple to create a custom form component with Vue. Tags are often a requirement for complex forms, but it doesn’t mean that the implementation has to be complex as well. Of course, there is no CSS at all, but it’s not a big deal to format the component.

If you want to test a working example you can visit this link: https://jsfiddle.net/ac6uvwhr/4/.

Special thanks for the following recource(s): Icon made by Smashicons from www.flaticon.com
Need a web developer? Maybe we can help, get in touch!