🚀Vue 3 + Element Plus 实现产品标签的动态添加、删除与回显
在后台管理系统中,我们经常需要对表单数据进行动态处理,尤其是类似"产品标签"这样的字段,它需要用户能够灵活添加、删除 ,并在编辑时自动回显。今天我们就来聊聊如何在 Vue 3 + Element Plus 中实现这一功能。
🛠️ 项目背景
本文案例来自于一个产品表单,包含字段如产品名称、活动时间、联系方式、以及我们今天重点讲的 ------ 产品标签。
🔧 实现效果
- 用户可点击"+ 添加产品标签"输入并添加标签;
- 支持删除已添加的标签;
- 编辑已有产品时,自动回显之前保存的标签。
💡 核心实现代码解析
1️⃣ 定义响应式变量
ts
import { nextTick, ref, reactive } from 'vue'
import { ElInput } from 'element-plus'
const dynamicTags = ref<string[]>([]) // 标签数组
const inputValue = ref('') // 当前输入的标签内容
const inputVisible = ref(false) // 控制输入框显示
const InputRef = ref<InstanceType<typeof ElInput>>() // 输入框引用
2️⃣ 显示标签并支持删除
vue
<el-form-item label="产品标签" prop="productsLabel">
<el-tag
v-for="tag in dynamicTags"
:key="tag"
class="mx-1"
closable
@close="handleClose(tag)"
>
{{ tag }}
</el-tag>
<el-input
v-if="inputVisible"
ref="InputRef"
v-model="inputValue"
class="ml-1 w-20"
@keyup.enter="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else class="button-new-tag ml-1" @click="showInput">
+ 添加产品标签
</el-button>
</el-form-item>
3️⃣ 添加标签逻辑
ts
const showInput = () => {
inputVisible.value = true
nextTick(() => {
InputRef.value!.input!.focus()
})
}
const handleInputConfirm = () => {
if (inputValue.value) {
dynamicTags.value.push(inputValue.value)
formData.value.productsLabel = dynamicTags.value // 同步到表单
}
inputVisible.value = false
inputValue.value = ''
}
4️⃣ 删除标签逻辑
ts
const handleClose = (tag: string) => {
dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)
formData.value.productsLabel = dynamicTags.value // 同步数据
}
5️⃣ 数据回显(编辑时)
当打开弹窗并传入产品 ID 时,从后端获取数据并赋值给标签数组:
ts
if (id) {
formData.value = await ProductsApi.getProducts(id)
dynamicTags.value = formData.value.productsLabel || []
}
✅ 小结
通过上述方式,我们轻松实现了:
- 标签的动态添加与删除;
- 输入框的显隐控制;
- 标签的同步绑定与数据回显。
该方式通用性强,特别适用于任何需要动态标签管理的场景。
🌟 标签功能扩展:数量限制 + 防重复 + 校验非空
✅ 一、限制标签数量(如最多 5 个)
添加一个判断逻辑,在添加标签前先判断当前数量是否超过上限:
ts
const MAX_TAGS = 5
const handleInputConfirm = () => {
const val = inputValue.value?.trim()
if (!val) {
message.warning('标签不能为空')
inputVisible.value = false
return
}
if (dynamicTags.value.length >= MAX_TAGS) {
message.warning(`最多添加 ${MAX_TAGS} 个标签`)
} else if (dynamicTags.value.includes(val)) {
message.warning('标签不能重复')
} else {
dynamicTags.value.push(val)
formData.value.productsLabel = dynamicTags.value // 同步数据
}
inputVisible.value = false
inputValue.value = ''
}
✅ 二、防止重复标签
上面的逻辑里其实已经包含了去重的判断:
ts
if (dynamicTags.value.includes(val)) {
message.warning('标签不能重复')
}
✅ 三、标签不能为空或纯空格
同样通过 .trim()
判断输入有效性:
ts
const val = inputValue.value?.trim()
if (!val) {
message.warning('标签不能为空')
inputVisible.value = false
return
}
✨ 提示消息组件
message.warning()
是 Element Plus 的 $message
组件调用,你需要确保有导入:
ts
const message = useMessage()
或者换成:
ts
import { ElMessage } from 'element-plus'
// 使用时 ElMessage.warning('...')
🧪 小技巧:展示当前标签数量
你也可以在 UI 上加点提示,比如:
vue
<small class="text-gray-500">已添加 {{ dynamicTags.length }}/{{ MAX_TAGS }} 个标签</small>