效果示意图:
![](https://i-blog.csdnimg.cn/direct/76b9da6c6bbe4835a3e78451b8374189.png)
组件代码:
<template>
<div class="custom-tag">
<input
v-if="tag.editing"
v-model="localText"
@blur="handleBlur"
@keyup.enter="handleBlur"
@input="adjustInputWidth"
ref="inputRef"
class="tag-input"
/>
<span v-else>{{ tag.text }}</span>
<CloseOutlined @click="$emit('remove')" class="small-icon" />
</div>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue';
import { CloseOutlined } from '@ant-design/icons-vue';
const props = defineProps({
tag: {
type: Object,
required: true
}
});
const emit = defineEmits(['update:tag', 'remove']);
const localText = ref(props.tag.text);
const editing = ref(props.tag.editing);
const inputRef = ref(null);
watch(
() => props.tag.text,
(newText) => {
localText.value = newText;
}
);
const handleBlur = () => {
editing.value = false;
emit('update:tag', {
...props.tag,
text: localText.value,
editing: editing.value
});
};
const adjustInputWidth = () => {
nextTick(() => {
if (inputRef.value) {
inputRef.value.style.width = `${inputRef.value.scrollWidth}px`;
}
});
};
</script>
<style scoped>
.custom-tag {
display: flex;
align-items: center;
margin-right: 5px;
background-color: #ff811a;
border-radius: 4px;
padding: 2px 5px;
color: white;
}
.tag-input {
border: none;
background-color: #ff811a;
padding: 0 5px;
border-radius: 4px;
color: white;
outline: none; /* 去掉输入框聚焦时的默认边框 */
width: 25px; /* 设置初始宽度 */
min-width: 25px; /* 设置最小宽度 */
box-sizing: border-box; /* 确保内边距和边框包含在宽度内 */
}
.small-icon {
font-size: 0.5em; /* 将图标大小缩小为原来的一半 */
cursor: pointer;
color: white;
margin-left: 5px; /* 增加一些间距,使图标更明显 */
}
.small-icon:hover {
color: #ffcc00; /* 悬停时改变颜色 */
}
</style>
父组件中使用方法:
<div style="display: flex; margin-bottom: 5px">
关键字:
<tags
v-for="(tag, index) in tagsList"
:key="index"
:tag="tag"
@remove="removeTag(index)"
/>
<div
v-show="tagsList.length < 5"
style="color: #ff811a"
@click="addKey"
>
+关键字
</div>
</div>
const addKey = () => {
tagsList.value.push({ text: '', editing: true });
};
const removeTag = (index) => {
console.log('tagsList', tagsList);
tagsList.value.splice(index, 1);
};