vue实现一个标签选择
Vue 标签选择实现
基础实现
创建一个基础的标签选择组件,包含标签的添加、删除和选择功能。
<template>
<div class="tag-selector">
<div class="selected-tags">
<span v-for="(tag, index) in selectedTags" :key="index" class="tag">
{{ tag }}
<button @click="removeTag(index)">×</button>
</span>
</div>
<input
v-model="newTag"
@keydown.enter="addTag"
placeholder="输入标签后按回车"
/>
</div>
</template>
<script>
export default {
data() {
return {
selectedTags: [],
newTag: ''
}
},
methods: {
addTag() {
if (this.newTag.trim() && !this.selectedTags.includes(this.newTag)) {
this.selectedTags.push(this.newTag.trim())
this.newTag = ''
}
},
removeTag(index) {
this.selectedTags.splice(index, 1)
}
}
}
</script>
<style>
.tag-selector {
border: 1px solid #ddd;
padding: 8px;
border-radius: 4px;
}
.selected-tags {
margin-bottom: 8px;
}
.tag {
display: inline-block;
background: #eee;
padding: 4px 8px;
margin-right: 4px;
border-radius: 4px;
}
.tag button {
background: none;
border: none;
cursor: pointer;
margin-left: 4px;
}
input {
border: none;
outline: none;
width: 100%;
}
</style>
带自动补全功能
实现带自动补全的标签选择器,提供候选标签列表。
<template>
<div class="tag-autocomplete">
<div class="selected-tags">
<span v-for="(tag, index) in selectedTags" :key="index" class="tag">
{{ tag }}
<button @click="removeTag(index)">×</button>
</span>
</div>
<input
v-model="searchQuery"
@input="filterTags"
@keydown.enter="addTag"
placeholder="输入标签"
/>
<ul v-if="filteredTags.length" class="suggestions">
<li
v-for="(tag, index) in filteredTags"
:key="index"
@click="selectTag(tag)"
>
{{ tag }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
selectedTags: [],
allTags: ['Vue', 'React', 'Angular', 'JavaScript', 'TypeScript'],
filteredTags: [],
searchQuery: ''
}
},
methods: {
filterTags() {
if (this.searchQuery) {
this.filteredTags = this.allTags.filter(tag =>
tag.toLowerCase().includes(this.searchQuery.toLowerCase())
)
} else {
this.filteredTags = []
}
},
selectTag(tag) {
if (!this.selectedTags.includes(tag)) {
this.selectedTags.push(tag)
}
this.searchQuery = ''
this.filteredTags = []
},
addTag() {
if (
this.searchQuery.trim() &&
!this.selectedTags.includes(this.searchQuery)
) {
this.selectedTags.push(this.searchQuery.trim())
this.searchQuery = ''
this.filteredTags = []
}
},
removeTag(index) {
this.selectedTags.splice(index, 1)
}
}
}
</script>
<style>
.tag-autocomplete {
position: relative;
border: 1px solid #ddd;
padding: 8px;
border-radius: 4px;
}
.selected-tags {
margin-bottom: 8px;
}
.tag {
display: inline-block;
background: #eee;
padding: 4px 8px;
margin-right: 4px;
border-radius: 4px;
}
.tag button {
background: none;
border: none;
cursor: pointer;
margin-left: 4px;
}
input {
border: none;
outline: none;
width: 100%;
}
.suggestions {
position: absolute;
left: 0;
right: 0;
background: white;
border: 1px solid #ddd;
list-style: none;
padding: 0;
margin: 0;
z-index: 10;
}
.suggestions li {
padding: 8px;
cursor: pointer;
}
.suggestions li:hover {
background: #f5f5f5;
}
</style>
使用第三方库
使用第三方库如vue-tags-input可以快速实现更丰富的标签选择功能。
安装:
npm install @voerro/vue-tagsinput
使用示例:
<template>
<tags-input
v-model="tags"
:existing-tags="existingTags"
:typeahead="true"
placeholder="添加标签"
/>
</template>
<script>
import TagsInput from '@voerro/vue-tagsinput'
export default {
components: { TagsInput },
data() {
return {
tags: [],
existingTags: [
{ key: 'vue', value: 'Vue' },
{ key: 'react', value: 'React' },
{ key: 'angular', value: 'Angular' }
]
}
}
}
</script>
注意事项
- 标签去重处理很重要,避免重复添加相同标签
- 考虑添加标签数量限制,防止用户添加过多标签
- 移动端适配需要考虑触摸事件的处理
- 性能优化:当标签列表很大时,考虑虚拟滚动或分页加载







