【Vue3 Element UI - Plus + Tyscript 实现Tags标签输入及回显】

发布于:2025-03-07 ⋅ 阅读:(26) ⋅ 点赞:(0)

Vue3 + Element Plus + TypeScript 实现 Tags 标签输入及回显

在开发后台管理系统或表单页面时,动态标签(Tags) 是一个常见的功能需求。用户可以通过输入框添加标签,并通过关闭按钮删除标签,同时还需要支持标签数据的提交和回显。本文将详细介绍如何使用 Vue 3Element PlusTypeScript 实现这一功能。我们的CSDN发布一栏也是相同的功能。
在这里插入图片描述
在这里插入图片描述


1. 功能需求

我们需要实现以下功能:

  1. 动态添加标签:用户可以通过输入框添加新的标签。
  2. 动态删除标签:用户可以点击标签的关闭按钮删除标签。
  3. 标签数据提交:将标签数据绑定到表单的 productsLabel 字段,随表单一起提交。
  4. 标签数据回显:在编辑表单时,从接口获取已保存的标签数据并展示。

2. 技术实现

官网上也有实现方式 https://element-plus.org/zh-CN/component/tag.html
在这里插入图片描述

2.1 动态标签的实现

动态标签的核心是通过 v-for 渲染标签列表,并使用 el-tag 组件展示标签。用户可以通过输入框添加新标签,并通过关闭按钮删除标签。

关键代码
<el-form-item label="产品标签" prop="productsLabel">
  <el-tag
    v-for="tag in dynamicTags"
    :key="tag"
    class="mx-1"
    closable
    :disable-transitions="false"
    @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>
代码解析
  1. el-tag 组件

    • 使用 v-for 遍历 dynamicTags 数组,渲染已添加的标签。
    • closable 属性为标签添加关闭按钮,点击关闭按钮时触发 handleClose 方法。
  2. el-input 组件

    • inputVisibletrue 时,显示输入框,用户可以在输入框中输入新标签。
    • 输入框支持按下回车键(@keyup.enter)或失去焦点(@blur)时触发 handleInputConfirm 方法,将输入的内容添加到标签列表。
  3. el-button 组件

    • inputVisiblefalse 时,显示“添加产品标签”按钮,点击按钮后显示输入框。

2.2 标签的添加与删除

标签的添加和删除通过以下方法实现:

关键代码
const inputValue = ref('') // 输入框的值
const dynamicTags = ref<string[]>([]) // 动态标签数组
const inputVisible = ref(false) // 控制输入框的显示
const InputRef = ref<InstanceType<typeof ElInput>>() // 输入框的引用

// 删除标签
const handleClose = (tag: string) => {
  dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)
  formData.value.productsLabel = dynamicTags.value // 同步到表单数据
}

// 显示输入框
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 = '' // 清空输入框
}
代码解析
  1. handleClose 方法

    • dynamicTags 数组中删除指定的标签。
    • 将更新后的标签数组同步到表单的 productsLabel 字段。
  2. showInput 方法

    • 显示输入框,并通过 nextTick 确保输入框渲染完成后自动聚焦。
  3. handleInputConfirm 方法

    • 将输入框的值添加到 dynamicTags 数组中。
    • 将更新后的标签数组同步到表单的 productsLabel 字段。
    • 隐藏输入框并清空输入框的值。

2.3 标签数据的回显

在编辑表单时,需要从接口获取已保存的标签数据并回显到页面上。

关键代码
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  if (id) {
    formLoading.value = true
    try {
      formData.value = await ProductsApi.getProducts(id) // 获取表单数据
      dynamicTags.value = formData.value.productsLabel || [] // 回显标签数据
    } finally {
      formLoading.value = false
    }
  }
}
代码解析
  1. open 方法
    • 打开表单弹窗时,如果是编辑模式(id 存在),则调用接口获取表单数据。
    • 将接口返回的 productsLabel 字段赋值给 dynamicTags,实现标签数据的回显。

2.4 标签数据的提交

标签数据通过 formData.productsLabel 字段随表单一起提交。

关键代码
const submitForm = async () => {
  try {
    await formRef.value.validate() // 表单验证
    formLoading.value = true
    const data = formData.value as unknown as ProductsVO
    if (formType.value === 'create') {
      await ProductsApi.createProducts(data) // 创建产品
    } else {
      await ProductsApi.updateProducts(data) // 更新产品
    }
    dialogVisible.value = false
    emit('success') // 提交成功后触发事件
  } catch (error) {
    console.error('表单提交失败:', error)
    message.error(t('common.submitFailed'))
  } finally {
    formLoading.value = false
  }
}
代码解析
  1. submitForm 方法
    • 在表单提交时,formData.productsLabel 字段会包含用户添加的所有标签数据。
    • 根据 formType 的值,调用创建或更新接口,将标签数据提交到后端。

3. 注意事项

  1. 标签去重

    • handleInputConfirm 方法中,建议添加去重逻辑,避免用户输入重复的标签。例如:
      if (inputValue.value && !dynamicTags.value.includes(inputValue.value)) {
        dynamicTags.value.push(inputValue.value)
      }
      
  2. 输入框验证

    • 可以为输入框添加验证规则,限制标签的长度或内容格式。例如:
      • 限制标签长度:if (inputValue.value.length > 10) { message.error('标签长度不能超过10个字符') }
      • 限制特殊字符:使用正则表达式检查输入内容是否合法。
  3. 性能优化

    • 如果标签数量较多,建议使用虚拟滚动(Virtual Scroll)技术优化渲染性能,避免页面卡顿。
    • 可以使用 el-tageffect 属性(如 darklight)优化标签的视觉效果。
  4. 用户体验优化

    • 在用户输入标签时,提供实时提示(如“按回车键添加标签”),提升交互体验。
    • 在标签数量较多时,可以添加滚动条或分页功能,避免页面布局混乱。
  5. 国际化支持

    • 使用 useI18n 实现标签相关文本的国际化,确保多语言环境下功能正常。例如:
      const { t } = useI18n()
      const addTagText = t('form.addTag') // 添加标签
      const tagLimitText = t('form.tagLimit') // 标签长度不能超过10个字符
      
  6. 数据同步

    • 确保 dynamicTagsformData.productsLabel 的数据同步,避免表单提交时遗漏标签数据。
    • 在编辑模式下,从接口获取数据后,及时将 productsLabel 赋值给 dynamicTags,确保标签正确回显。
  7. 错误处理

    • 在标签添加或删除时,增加错误处理逻辑。例如,如果标签添加失败,可以显示错误提示并恢复原有状态。
  8. 浏览器兼容性

    • 测试不同浏览器下的表现,确保功能在主流浏览器(如 Chrome、Firefox、Safari)中正常运行。

4. 总结

通过以上实现,我们完成了动态标签的添加、删除、提交和回显功能。这个功能的核心在于:

  • 使用 v-for 动态渲染标签列表。
  • 通过 el-inputel-tag 实现标签的输入和展示。
  • 将标签数据绑定到表单的 productsLabel 字段,实现数据的提交和回显。

希望这篇文章对你有帮助!如果有任何问题,欢迎在评论区留言讨论~