Custom tag content slot
The following example demonstrates how to use the VueSelect component with the #tag-content slot when using the isMulti prop.
What is the #tag-content slot?
The #tag-content slot allows you to customize only the text content inside a multi-select tag, while automatically preserving:
- The tag wrapper structure
- Default styling (background, padding, borders)
- The remove button
- Event handlers for removing tags
This makes it much simpler than the #tag slot when you only want to change how the label text is displayed.
When to use #tag-content vs #tag
Use #tag-content when:
- You only want to format or transform the label text
- You want to add icons, badges, or emphasis to the text
- You want to keep the default tag styling and remove button
Use #tag when:
- You need complete control over the tag structure
- You want custom styling that can't be achieved with CSS variables
- You need to change the remove button appearance or behavior
INFO
Read more about available slots here, the #tag slot here, and the isMulti prop here.
Demo source-code
vue
<script setup>
import { ref } from "vue";
import VueSelect from "vue3-select-component";
const selected = ref([]);
const skillOptions = [
{ label: "JavaScript", value: "javascript", level: "expert", icon: "🟨" },
{ label: "TypeScript", value: "typescript", level: "expert", icon: "🔷" },
{ label: "Vue.js", value: "vue", level: "expert", icon: "💚" },
{ label: "React", value: "react", level: "intermediate", icon: "⚛️" },
{ label: "Python", value: "python", level: "beginner", icon: "🐍" },
{ label: "Rust", value: "rust", level: "beginner", icon: "🦀" },
];
const levelColors = {
beginner: "#93c5fd",
intermediate: "#86efac",
expert: "#fde047",
};
</script>
<template>
<VueSelect
v-model="selected"
:is-multi="true"
:options="skillOptions"
placeholder="Select your skills"
>
<template #tag-content="{ option }">
<span :style="{ display: 'flex', alignItems: 'center', gap: '4px' }">
<span>{{ option.icon }}</span>
<strong>{{ option.label }}</strong>
<span
:style="{
fontSize: '10px',
padding: '2px 4px',
borderRadius: '2px',
backgroundColor: levelColors[option.level],
color: '#000',
fontWeight: 500,
}"
>
{{ option.level }}
</span>
</span>
</template>
</VueSelect>
</template>Key Benefits
- Simpler Implementation: No need to recreate the tag structure or remove button
- Consistent Styling: Automatically inherits all CSS variables for tags
- Type Safety: Full TypeScript support with option typing
- Less Code: Focus only on the content formatting
- Maintainability: Future component updates automatically apply
Comparison: #tag vs #tag-content
With #tag-content (Simpler)
html
<template #tag-content="{ option }">
<strong>{{ option.label }}</strong>
</template>The component handles:
- Tag wrapper (
<div class="multi-value">) - Remove button with icon
- Click handlers
- Styling with CSS variables
With #tag (Full Control)
html
<template #tag="{ option, removeOption }">
<div class="custom-tag">
<strong>{{ option.label }}</strong>
<button @click="removeOption">×</button>
</div>
</template>You must handle:
- Complete tag structure
- Custom button and event handler
- All styling from scratch
