【Vue 3 + Element Plus 实现产品标签的动态添加、删除与回显】


🚀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>

相关推荐
倾颜3 小时前
从 textarea 到 AI 输入框:用 Tiptap 实现 / 命令、@ 引用和结构化请求
前端·langchain·next.js
kyriewen4 小时前
程序员连夜带团队跑路,省了23万:这AI太贵,真的用不起了
前端·javascript·openai
kyriewen5 小时前
你写的代码没有测试,就像出门不锁门——Jest + Testing Library 从入门到不慌
前端·单元测试·jest
yuzhiboyouye6 小时前
web前端英语面试
前端·面试·状态模式
canonical_entropy7 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
东方小月7 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构
我叫黑大帅7 小时前
为什么需要 @types/react?解决“无法找到模块 react 的声明文件”报错
前端·javascript·面试
之歆7 小时前
DAY_21JavaScript 深度解析:数组(Array)与函数(Function)(一)
前端·javascript
XinZong8 小时前
【AI社交】基于OpenClaw自研轻量化AI社交平台实战
前端
Le_ee8 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php