vue实现一个标签选择
Vue 标签选择组件实现
基础实现
使用 Vue 的 v-for 和 v-model 指令可以快速实现标签选择功能:
<template>
<div class="tag-selector">
<div
v-for="tag in availableTags"
:key="tag"
class="tag"
:class="{ 'selected': selectedTags.includes(tag) }"
@click="toggleTag(tag)"
>
{{ tag }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
availableTags: ['前端', '后端', '移动端', '数据库', '运维'],
selectedTags: []
}
},
methods: {
toggleTag(tag) {
const index = this.selectedTags.indexOf(tag)
if (index === -1) {
this.selectedTags.push(tag)
} else {
this.selectedTags.splice(index, 1)
}
}
}
}
</script>
<style>
.tag-selector {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag {
padding: 4px 12px;
border: 1px solid #ddd;
border-radius: 16px;
cursor: pointer;
}
.tag.selected {
background-color: #42b983;
color: white;
border-color: #42b983;
}
</style>
可编辑标签实现
实现允许用户添加新标签的功能:

<template>
<div>
<input
v-model="newTag"
@keyup.enter="addTag"
placeholder="输入新标签"
/>
<button @click="addTag">添加</button>
<div class="tag-container">
<span
v-for="tag in tags"
:key="tag"
class="tag"
@click="removeTag(tag)"
>
{{ tag }} ×
</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tags: ['Vue', 'React', 'Angular'],
newTag: ''
}
},
methods: {
addTag() {
if (this.newTag.trim() && !this.tags.includes(this.newTag)) {
this.tags.push(this.newTag)
this.newTag = ''
}
},
removeTag(tag) {
this.tags = this.tags.filter(t => t !== tag)
}
}
}
</script>
带搜索的标签选择器
结合输入搜索功能:
<template>
<div>
<input
v-model="searchQuery"
placeholder="搜索标签..."
/>
<div v-if="filteredTags.length">
<div
v-for="tag in filteredTags"
:key="tag"
class="tag-item"
@click="selectTag(tag)"
>
{{ tag }}
</div>
</div>
<div v-else>
没有匹配的标签
</div>
<div class="selected-tags">
已选择: {{ selectedTags.join(', ') }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
allTags: ['JavaScript', 'TypeScript', 'HTML', 'CSS', 'Node.js'],
selectedTags: [],
searchQuery: ''
}
},
computed: {
filteredTags() {
return this.allTags.filter(tag =>
tag.toLowerCase().includes(this.searchQuery.toLowerCase()) &&
!this.selectedTags.includes(tag)
)
}
},
methods: {
selectTag(tag) {
this.selectedTags.push(tag)
this.searchQuery = ''
}
}
}
</script>
组件封装
将标签选择器封装为可复用组件:

<!-- TagSelector.vue -->
<template>
<div class="tag-selector">
<div class="selected-tags">
<span
v-for="tag in modelValue"
:key="tag"
class="tag"
@click="removeTag(tag)"
>
{{ tag }} ×
</span>
</div>
<input
v-model="searchQuery"
@keydown.enter="addNewTag"
placeholder="添加标签..."
/>
<div v-if="filteredTags.length" class="tag-options">
<div
v-for="tag in filteredTags"
:key="tag"
class="tag-option"
@click="selectTag(tag)"
>
{{ tag }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: Array,
required: true
},
availableTags: {
type: Array,
default: () => []
}
},
data() {
return {
searchQuery: ''
}
},
computed: {
filteredTags() {
return this.availableTags.filter(tag =>
tag.toLowerCase().includes(this.searchQuery.toLowerCase()) &&
!this.modelValue.includes(tag)
)
}
},
methods: {
selectTag(tag) {
this.$emit('update:modelValue', [...this.modelValue, tag])
this.searchQuery = ''
},
removeTag(tag) {
this.$emit('update:modelValue', this.modelValue.filter(t => t !== tag))
},
addNewTag() {
if (this.searchQuery.trim() && !this.modelValue.includes(this.searchQuery)) {
this.$emit('update:modelValue', [...this.modelValue, this.searchQuery])
this.searchQuery = ''
}
}
}
}
</script>
使用封装的组件:
<template>
<TagSelector
v-model="selectedTags"
:available-tags="allTags"
/>
</template>
<script>
import TagSelector from './TagSelector.vue'
export default {
components: { TagSelector },
data() {
return {
allTags: ['Vue', 'React', 'Angular', 'Svelte'],
selectedTags: []
}
}
}
</script>
第三方库方案
使用 vue-tags-input 等现成库:
npm install @voerro/vue-tagsinput
<template>
<tags-input
v-model="tags"
:existing-tags="availableTags"
:typeahead="true"
placeholder="添加标签"
/>
</template>
<script>
import VoerroTagsInput from '@voerro/vue-tagsinput'
export default {
components: {
'tags-input': VoerroTagsInput
},
data() {
return {
tags: [],
availableTags: [
{ key: 'vue', value: 'Vue.js' },
{ key: 'react', value: 'React' }
]
}
}
}
</script>
这些实现方案覆盖了从基础到高级的标签选择功能,可以根据项目需求选择合适的实现方式。






