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


1. 功能需求
我们需要实现以下功能:
- 动态添加标签:用户可以通过输入框添加新的标签。
- 动态删除标签:用户可以点击标签的关闭按钮删除标签。
- 标签数据提交:将标签数据绑定到表单的
productsLabel字段,随表单一起提交。 - 标签数据回显:在编辑表单时,从接口获取已保存的标签数据并展示。
2. 技术实现
官网上也有实现方式 https://element-plus.org/zh-CN/component/tag.html

2.1 动态标签的实现
动态标签的核心是通过 v-for 渲染标签列表,并使用 el-tag 组件展示标签。用户可以通过输入框添加新标签,并通过关闭按钮删除标签。
关键代码
<el-form-item label="产品标签" prop="productsLabel"><el-tagv-for="tag in dynamicTags":key="tag"class="mx-1"closable:disable-transitions="false"@close="handleClose(tag)">{{ tag }}</el-tag><el-inputv-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>
代码解析
-
el-tag组件:- 使用
v-for遍历dynamicTags数组,渲染已添加的标签。 closable属性为标签添加关闭按钮,点击关闭按钮时触发handleClose方法。
- 使用
-
el-input组件:- 当
inputVisible为true时,显示输入框,用户可以在输入框中输入新标签。 - 输入框支持按下回车键(
@keyup.enter)或失去焦点(@blur)时触发handleInputConfirm方法,将输入的内容添加到标签列表。
- 当
-
el-button组件:- 当
inputVisible为false时,显示“添加产品标签”按钮,点击按钮后显示输入框。
- 当
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 = truenextTick(() => {InputRef.value!.input!.focus() // 自动聚焦输入框})
}// 确认输入
const handleInputConfirm = () => {if (inputValue.value) {dynamicTags.value.push(inputValue.value) // 添加新标签formData.value.productsLabel = dynamicTags.value // 同步到表单数据}inputVisible.value = false // 隐藏输入框inputValue.value = '' // 清空输入框
}
代码解析
-
handleClose方法:- 从
dynamicTags数组中删除指定的标签。 - 将更新后的标签数组同步到表单的
productsLabel字段。
- 从
-
showInput方法:- 显示输入框,并通过
nextTick确保输入框渲染完成后自动聚焦。
- 显示输入框,并通过
-
handleInputConfirm方法:- 将输入框的值添加到
dynamicTags数组中。 - 将更新后的标签数组同步到表单的
productsLabel字段。 - 隐藏输入框并清空输入框的值。
- 将输入框的值添加到
2.3 标签数据的回显
在编辑表单时,需要从接口获取已保存的标签数据并回显到页面上。
关键代码
const open = async (type: string, id?: number) => {dialogVisible.value = truedialogTitle.value = t('action.' + type)formType.value = typeresetForm()if (id) {formLoading.value = truetry {formData.value = await ProductsApi.getProducts(id) // 获取表单数据dynamicTags.value = formData.value.productsLabel || [] // 回显标签数据} finally {formLoading.value = false}}
}
代码解析
open方法:- 打开表单弹窗时,如果是编辑模式(
id存在),则调用接口获取表单数据。 - 将接口返回的
productsLabel字段赋值给dynamicTags,实现标签数据的回显。
- 打开表单弹窗时,如果是编辑模式(
2.4 标签数据的提交
标签数据通过 formData.productsLabel 字段随表单一起提交。
关键代码
const submitForm = async () => {try {await formRef.value.validate() // 表单验证formLoading.value = trueconst data = formData.value as unknown as ProductsVOif (formType.value === 'create') {await ProductsApi.createProducts(data) // 创建产品} else {await ProductsApi.updateProducts(data) // 更新产品}dialogVisible.value = falseemit('success') // 提交成功后触发事件} catch (error) {console.error('表单提交失败:', error)message.error(t('common.submitFailed'))} finally {formLoading.value = false}
}
代码解析
submitForm方法:- 在表单提交时,
formData.productsLabel字段会包含用户添加的所有标签数据。 - 根据
formType的值,调用创建或更新接口,将标签数据提交到后端。
- 在表单提交时,
3. 注意事项
-
标签去重:
- 在
handleInputConfirm方法中,建议添加去重逻辑,避免用户输入重复的标签。例如:if (inputValue.value && !dynamicTags.value.includes(inputValue.value)) {dynamicTags.value.push(inputValue.value) }
- 在
-
输入框验证:
- 可以为输入框添加验证规则,限制标签的长度或内容格式。例如:
- 限制标签长度:
if (inputValue.value.length > 10) { message.error('标签长度不能超过10个字符') } - 限制特殊字符:使用正则表达式检查输入内容是否合法。
- 限制标签长度:
- 可以为输入框添加验证规则,限制标签的长度或内容格式。例如:
-
性能优化:
- 如果标签数量较多,建议使用虚拟滚动(Virtual Scroll)技术优化渲染性能,避免页面卡顿。
- 可以使用
el-tag的effect属性(如dark或light)优化标签的视觉效果。
-
用户体验优化:
- 在用户输入标签时,提供实时提示(如“按回车键添加标签”),提升交互体验。
- 在标签数量较多时,可以添加滚动条或分页功能,避免页面布局混乱。
-
国际化支持:
- 使用
useI18n实现标签相关文本的国际化,确保多语言环境下功能正常。例如:const { t } = useI18n() const addTagText = t('form.addTag') // 添加标签 const tagLimitText = t('form.tagLimit') // 标签长度不能超过10个字符
- 使用
-
数据同步:
- 确保
dynamicTags和formData.productsLabel的数据同步,避免表单提交时遗漏标签数据。 - 在编辑模式下,从接口获取数据后,及时将
productsLabel赋值给dynamicTags,确保标签正确回显。
- 确保
-
错误处理:
- 在标签添加或删除时,增加错误处理逻辑。例如,如果标签添加失败,可以显示错误提示并恢复原有状态。
-
浏览器兼容性:
- 测试不同浏览器下的表现,确保功能在主流浏览器(如 Chrome、Firefox、Safari)中正常运行。
4. 总结
通过以上实现,我们完成了动态标签的添加、删除、提交和回显功能。这个功能的核心在于:
- 使用
v-for动态渲染标签列表。 - 通过
el-input和el-tag实现标签的输入和展示。 - 将标签数据绑定到表单的
productsLabel字段,实现数据的提交和回显。
希望这篇文章对你有帮助!如果有任何问题,欢迎在评论区留言讨论~
相关文章:
【Vue3 Element UI - Plus + Tyscript 实现Tags标签输入及回显】
Vue3 Element Plus TypeScript 实现 Tags 标签输入及回显 在开发后台管理系统或表单页面时,动态标签(Tags) 是一个常见的功能需求。用户可以通过输入框添加标签,并通过关闭按钮删除标签,同时还需要支持标签数据的提…...
STM32 子设备通过CAN发送数据到主设备
采集ADC、GPS经纬坐标、温湿度数据、大气压数据通过CAN方式发送给主设备端,帧ID按照如下定义: 我尼玛一个标准帧ID位数据是11位,扩展帧才是111829位,它说最开头的是四位是真类型,并给我如下解释: 它把帧的定…...
Python可视化——地理空间型图表(自用)
地图信息可视化的实现就是将不可展开的曲面上的地理坐标信息转化为二维平面进行显示,这个过程也叫地图投影(空间三维投影到平面二维) 地图投影的要求:等面积、等角度、等距离。总的来说就是映射到二维平面中的任何点通过比例尺放大…...
WordPress报502错误问题解决-php-fpm-84.service loaded failed failed LSB: starts php-fpm
文章目录 问题描述问题排查问题解决 问题描述 服务器环境: php:8.4MySQL:8.0Nginx:1.26.2 在访问站点时,一直报502,而两天前还能正常访问。 问题排查 导致502的问题很多,比如站点访问量太大…...
Python在SEO中的自动化应用爬虫开发与日志分析实例
引言 搜索引擎优化(SEO)是数字营销中至关重要的一环,旨在提高网站在搜索引擎结果页面(SERP)中的排名。随着互联网数据的爆炸式增长,手动进行SEO分析和管理变得愈发困难。Python作为一种强大的编程语言&…...
thingsboard edge 在windows 环境下的配置
按照官方文档:Installing ThingsBoard Edge on Windows | ThingsBoard Edge,配置好java环境和PostgreSQL。 下载对应的windows 环境下的tb-edge安装包。下载附件 接下来操作具体如下 步骤1,需要先在thingsboard 服务上开启edge 权限 步骤2…...
nnMamba:基于状态空间模型的3D生物医学图像分割、分类和地标检测
摘要 本文提出了一种基于状态空间模型(SSMs)的创新架构——nnMamba,用于解决3D生物医学图像分割、分类及地标检测任务中的长距离依赖建模难题。nnMamba结合了卷积神经网络(CNN)的局部特征提取能力与SSMs的全局上下文建…...
nginx 配置403页面(已亲测)
问题:GET请求访问漏洞url即可看到泄露的内网ip 解决方式: 1.配置nginx 不显示真实Ip 2.限制接口只能是POST请求 具体配置: 编写一个403.html 在nginx的配置文件中,配置location参数: location /api/validationCode…...
SyntaxError: Invalid or unexpected token in JSON at position x
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
Uncaught TypeError: Cannot read properties of undefined (reading ‘xxx‘)
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
Nginx 跨域配置详细讲解
一、跨域请求概述 跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,它使用额外的HTTP头部来告诉浏览器让运行在一个origin(域)上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资…...
前端开发基石:HTML语义化深度解析与实践指南
一、语义化设计的本质价值 1.1 从文档结构到信息表达 在Web诞生初期(1991年),HTML仅包含18个标签用于学术文档展示。经过30年发展,HTML5已拥有超过110个标签,其中语义化标签占比提升至60%。这种演进背后是互联网从简…...
mongodb安装教程以及mongodb的使用
MongoDB是由C语言编写的一种面向文档的NoSQL数据库,旨在为WEB应用提供可扩展的高性能数据存储解决方案。与传统的关系型数据库(如 MySQL 或 PostgreSQL)不同,MongoDB 存储数据的方式是以 BSON(类似于 JSON 的二进制格式…...
C# 中的多线程同步机制:lock、Monitor 和 Mutex 用法详解
在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。C# 提供了几种常用的同步机制,其中 lock、Monitor 和 Mutex 是最常用的同步工具。本文将全面介绍这三种同步机制的用法、优缺点以及适用场景,帮助开发者在多线程开发中做…...
【通义万相】蓝耘智算 | 开源视频生成新纪元:通义万相2.1模型部署与测评
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT&…...
期权帮|中证1000股指期权交割结算价怎么算?
期权帮锦鲤三三每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 中证1000股指期权交割结算价怎么算? 一、按照最后交易日结算价: (1)计算方法:最后交易日标的指数(…...
Python 面向对象高级编程-定制类
目录 __str__ __iter__ __getitem__ __getattr__ __call__ 小结 看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。 __slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()…...
qt creator示例空白
通常情况下,进入qt后,就会弹出以下窗口: 但如果出现示例空白,那可能是因为 Qt Creator 无法正确识别 Qt 的安装路径或配置。 解决: 点击“添加”: 然后跳转到你的qmake.exe的目录,例如我的qmak…...
MyBatis-Plus 与 Spring Boot 的最佳实践
在现代 Java 开发中,MyBatis-Plus 和 Spring Boot 的结合已经成为了一种非常流行的技术栈。MyBatis-Plus 是 MyBatis 的增强工具,提供了许多便捷的功能,而 Spring Boot 则简化了 Spring 应用的开发流程。本文将探讨如何将 MyBatis-Plus 与 Spring Boot 进行整合,并分享一些…...
TDengine 中的标签索引
简介 本节说明 TDengine 的索引机制。在 TDengine 3.0.3.0 版本之前(不含),默认在第一列 TAG 上建立索引,但不支持给其它列动态添加索引。从 3.0.3.0 版本开始,可以动态地为其它 TAG 列添加索引。对于第一个 TAG 列上…...
MSE、MAE、Binary/Categorical Cross-Entropy、HingeLoss五种损失函数的典型应用场景
目录第一类:回归任务(预测具体数值)👓1. MSE (均方误差) —— 重罚离群点👓2. MAE (平均绝对误差) —— 鲁棒性强第二类:分类任务(判断属于哪一类)👓3. Binary Cross-Ent…...
threejs 加载glb模型时DRACOLoader的正确配置与常见错误解析
1. 为什么需要DRACOLoader? 在Three.js中加载glb/gltf模型时,经常会遇到模型文件过大的问题。这是因为很多3D建模工具(如Blender)在导出时会使用Draco压缩算法来减小文件体积。这种压缩虽然能显著减少模型大小(通常能…...
重构AI训练数据管理流程:BooruDatasetTagManager如何提升图像标签标注效率83%
重构AI训练数据管理流程:BooruDatasetTagManager如何提升图像标签标注效率83% 【免费下载链接】BooruDatasetTagManager 项目地址: https://gitcode.com/gh_mirrors/bo/BooruDatasetTagManager 在AI模型训练的数据准备阶段,图像标签管理是决定模…...
新手避坑指南:安捷伦/是德示波器探头选1MΩ还是50Ω?实测对比告诉你差别有多大
示波器探头阻抗选择实战手册:1MΩ与50Ω的黄金法则 第一次接触示波器时,我犯了个低级错误——用1MΩ探头直接测量射频电路,结果不仅波形畸变成锯齿状,还差点烧毁前端放大器。这个价值3000元的教训让我深刻认识到:探头…...
人工智能应用- 走向未来:02.人工智能研究方向
随着技术的发展,以深度神经网络为代表的人工智能技术在取得突破的同时,也逐渐暴露出一些基础性问题。这些问题促使科学家们思考人工智能的下一步发展。本节将从几个关键方面,探讨当前人工智能的重要研究方向。可解释性与可控性首先࿰…...
告别数据洪流:手把手教你用ZCANPRO的视图筛选与实时曲线功能高效分析CAN报文
告别数据洪流:手把手教你用ZCANPRO的视图筛选与实时曲线功能高效分析CAN报文 在车载电子和嵌入式开发领域,CAN总线数据的分析工作常常让工程师们头疼不已。想象一下,当你的测试设备捕获到成千上万条CAN报文时,如何从中快速定位到关…...
如何修复 n8n Postgres 节点中的“节点未设置任何凭据”错误:一篇真正能照着操作的排障博客
如果你在用 n8n 连 Postgres 的时候,突然看到一句让人有点懵的报错:Node has no credentials set 或者中文界面里类似:节点未设置任何凭据先别慌。这个报错看起来像系统在跟你打哑谜,但它的真实意思其实非常朴素: 这个…...
手把手教你搭建轻量级Gitea代码托管平台:Windows本地部署实战
1. 为什么选择Gitea作为本地代码托管平台 作为一个长期在Windows环境下开发的程序员,我深知一个轻量级代码托管平台的重要性。以前我也用过Gitblit这类工具,但随着项目复杂度提升,越来越需要一个更现代的解决方案。Gitea就像是为个人开发者量…...
终极美化指南:foobar2000如何通过foobox-cn打造你的专属音乐空间?
终极美化指南:foobar2000如何通过foobox-cn打造你的专属音乐空间? 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 厌倦了千篇一律的音乐播放器界面?想让你的音乐体…...
极简音乐工具:重新定义纯粹听歌体验
极简音乐工具:重新定义纯粹听歌体验 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特!(密码重置功能已回归) 项目地址: https://gitcode.com/GitHub_Trending/to/tonzhon-mus…...
