vue实现tag
Vue 实现 Tag 标签组件
基础实现
使用 Vue 的单文件组件(SFC)创建一个基本的 Tag 组件,包含关闭功能:
<template>
<span class="tag" :class="[type, { closable }]">
<slot></slot>
<span v-if="closable" class="close" @click="$emit('close')">×</span>
</span>
</template>
<script>
export default {
name: 'Tag',
props: {
closable: Boolean,
type: {
type: String,
default: 'default',
validator: value => ['default', 'success', 'warning', 'danger'].includes(value)
}
}
}
</script>
<style scoped>
.tag {
display: inline-flex;
align-items: center;
padding: 0 8px;
height: 24px;
line-height: 22px;
font-size: 12px;
border-radius: 4px;
border: 1px solid #d9d9d9;
background: #fafafa;
margin-right: 8px;
}
.tag.success {
color: #52c41a;
background: #f6ffed;
border-color: #b7eb8f;
}
.tag.warning {
color: #faad14;
background: #fffbe6;
border-color: #ffe58f;
}
.tag.danger {
color: #ff4d4f;
background: #fff2f0;
border-color: #ffccc7;
}
.close {
margin-left: 4px;
cursor: pointer;
}
</style>
动态标签组
实现可动态添加和删除的标签组组件:
<template>
<div class="tag-group">
<tag
v-for="(tag, index) in tags"
:key="index"
:closable="true"
@close="removeTag(index)"
>
{{ tag }}
</tag>
<input
v-if="inputVisible"
ref="input"
v-model="inputValue"
@keyup.enter="addTag"
@blur="addTag"
/>
<button v-else class="button" @click="showInput">+ New Tag</button>
</div>
</template>
<script>
import Tag from './Tag.vue'
export default {
components: { Tag },
data() {
return {
tags: ['标签1', '标签2', '标签3'],
inputVisible: false,
inputValue: ''
}
},
methods: {
removeTag(index) {
this.tags.splice(index, 1)
},
showInput() {
this.inputVisible = true
this.$nextTick(() => {
this.$refs.input.focus()
})
},
addTag() {
if (this.inputValue) {
this.tags.push(this.inputValue)
}
this.inputVisible = false
this.inputValue = ''
}
}
}
</script>
<style>
.tag-group {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.button {
height: 24px;
line-height: 22px;
padding: 0 8px;
background: #fff;
border: 1px dashed #d9d9d9;
border-radius: 4px;
cursor: pointer;
}
</style>
可编辑标签
实现双击可编辑的标签功能:
<template>
<span
class="editable-tag"
@dblclick="handleEdit"
v-click-outside="handleBlur"
>
<span v-if="!editing">{{ tag }}</span>
<input
v-else
ref="input"
v-model="editValue"
@keyup.enter="handleConfirm"
@blur="handleConfirm"
/>
<span class="close" @click="$emit('remove')">×</span>
</span>
</template>
<script>
export default {
props: {
tag: String
},
data() {
return {
editing: false,
editValue: this.tag
}
},
directives: {
'click-outside': {
bind(el, binding, vnode) {
el.clickOutsideEvent = function(event) {
if (!(el === event.target || el.contains(event.target))) {
vnode.context[binding.expression](event)
}
}
document.body.addEventListener('click', el.clickOutsideEvent)
},
unbind(el) {
document.body.removeEventListener('click', el.clickOutsideEvent)
}
}
},
methods: {
handleEdit() {
this.editing = true
this.$nextTick(() => {
this.$refs.input.focus()
})
},
handleBlur() {
this.editing = false
this.editValue = this.tag
},
handleConfirm() {
this.editing = false
if (this.editValue && this.editValue !== this.tag) {
this.$emit('edit', this.editValue)
}
}
}
}
</script>
与表单集成
将标签组件与 Vue 表单集成:
<template>
<div>
<tag-group v-model="selectedTags" :options="availableTags" />
<button @click="submit">提交</button>
</div>
</template>
<script>
import TagGroup from './TagGroup.vue'
export default {
components: { TagGroup },
data() {
return {
availableTags: ['Vue', 'React', 'Angular', 'Svelte'],
selectedTags: ['Vue']
}
},
methods: {
submit() {
console.log('Selected tags:', this.selectedTags)
}
}
}
</script>
以上实现涵盖了 Tag 组件的基本功能、动态标签组、可编辑标签以及与表单的集成,可以根据实际需求进行组合和扩展。







