Skip to content

Instantly share code, notes, and snippets.

@JavascriptMick
Last active January 28, 2024 02:08
Show Gist options
  • Save JavascriptMick/0a5113e90b069d3af5637de16070ea89 to your computer and use it in GitHub Desktop.
Save JavascriptMick/0a5113e90b069d3af5637de16070ea89 to your computer and use it in GitHub Desktop.
Simple Tag List Component in Vue 3 and Tailwind

TagList Component

Vue 3 + tailwind

uses v-model remove tags by clicking x add new tags by typing and pressing space, comma, period

<template>
<div
class="flex flex-wrap items-center border border-gray-300 rounded p-2"
id="tag-container">
<div
v-for="(tag, index) in modelValue"
:key="index"
class="flex items-center bg-gray-200 rounded px-3 py-1">
<span>{{ tag }}</span>
<button
class="ml-2 text-gray-600 hover:text-gray-800"
@click.prevent="removeItem(index)">
&times;
</button>
</div>
<input
type="text"
id="tag-input"
class="flex-1 border-none focus:ring-0"
@keypress.enter.prevent="doNothing"
@keyup.prevent="handleKeyPress"
placeholder="type a keyword and hit [space]" />
</div>
</template>
<script>
import { defineComponent, toRefs } from 'vue';
export default defineComponent({
name: 'TagList',
props: {
modelValue: Array
},
setup(props, { emit }) {
const { modelValue } = toRefs(props);
const doNothing = async event => {}; // null handler for enter to prevent odd invocation of removeItem when you press enter in the input box
const removeItem = index => {
const clonedValue = [...modelValue.value];
clonedValue.splice(index, 1);
emit('update:modelValue', clonedValue);
};
const handleKeyPress = async event => {
if (event.key === ' ' || event.key === ',' || event.key === '.') {
const trimmedValue = event.target.value.replace(/[,\s.]/g, '');
if (
trimmedValue &&
trimmedValue.length > 0 &&
!modelValue.value.includes(trimmedValue)
) {
console.log(`trimmedValue: ${trimmedValue}`);
const clonedValue = [...modelValue.value, trimmedValue];
await emit('update:modelValue', clonedValue);
}
event.target.value = '';
}
};
return {
modelValue,
removeItem,
handleKeyPress,
doNothing
};
}
});
</script>
<template>
<TagList
id="my-tags"
v-model="tags"
class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"></TagList>
</template>
<script setup>
import { ref } from 'vue';
const tags = ref(['aaa']);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment