vue封装组件(一)标签和下拉框组合实现添加数据

背景: 最近接入短剧内容,需要添加短剧合作方。在详情页需要支持添加组件 方案一:标签tag加上输入框实现添加数据。图片见下 这个是刚开始做的,后来产品觉得这样会造成随意修改数据,需要改成下拉框形式添加 方案二:标签tag加上下拉框以及添加按钮实现。 这个就避免了乱添加数据,添加合作方名字需要在一个管理页面添加,然后下拉框请求自然就请求到数据了

方案一效果图:第一行 流程:点击新增后,填入数据,后台会自动检查是否存在,存在返回数据,否则保存然后返回数据。 这样做有个问题,一不小心填错数据,后台也保存下来了 方案二效果图:第二行 流程:下拉框中是已经存在的数据,然后选择添加就行。合作方需要在另外的一个管理页面增删查改。

接下来是代码实现。 注意:这两个都是封装的组件,直接掉用即可,既然是封装的组件,那么就要支持已经存在的合作方数据填入。

方案一

<template><div>
<!--   {{shortPlays}}--><el-tag style="margin-right: 5px" v-for="(tag,index) in shortPlaysFilter":key="index" closable@close="close(index,tag.shortPlayName)">{{tag.shortPlayName}}</el-tag><el-inputv-if="inputVisible"v-model="inputValue"ref="ref"class="input-new-tag"size="small"style="width: 100px"@keyup.enter.native="inputConfirm"@blur="inputConfirm"></el-input><el-button v-else size="small" style="margin-left: 5px;" @click="btnClick">新增合作方</el-button></div></template><script>
import * as mapRequest from "@/api/map";export default {name: "ag_album_short_play_partner",props:{//这里外部的数据传入shortPlays:{required:true,default:()=>{return [];}}},data() {return {inputVisible:false,inputValue:'',}},created() {},methods: {close(index,name){// 注意:这里的index 不能直接拿到删除 因为这个index 是过滤后的 所以通过name找下标 然后删除console.log("name",name);let findex=this.shortPlays.findIndex(f=>f.shortPlayName==name);console.log("findex",findex);if(findex==-1 || findex<0){this.$message.error("删除短剧合作方失败!请联系开发人员");return;}//console.log(findex);let data=this.shortPlays[findex];console.log("data",data);if(data.id){// 存在id 说明本身就有合作方 标记删除this.$set(data,'delFlag',true);this.$emit('input',this.shortPlays);}else{this.shortPlays.splice(findex,1);this.$emit('input',this.shortPlays);}},btnClick(){this.inputVisible=true;this.$nextTick(()=>{this.$refs.ref.$refs.input.focus();})},inputConfirm(){let inputValue=this.inputValue;if(inputValue){mapRequest.addShortPlay({name:inputValue}).then(res=>{let data=res.data.data;this.shortPlays.push({addFlag:true,shortPlayId:data.id,shortPlayName:data.name});this.$emit('input',this.shortPlays);}).catch(err=>{this.$message.error("添加短剧合作方失败");console.log(err);})}this.inputVisible=false;this.inputValue='';}},computed: {shortPlaysFilter(){let obj=this.shortPlays.filter(item=>{if(item.delFlag&&item.delFlag==true) return false;return true;});return obj;}},watch: {},components: {},}
</script><style scoped></style>

这个就是封装的组件,然后想用的时候直接引用即可。

方案二

<!--
删除逻辑:
1、原始tags中有delFlag true 这种数据不能展示,所以用 filteredTags 过滤
2、如果是本来存在的删除时可以标记delFlag true,如果时添加后(没点击提交动作,数据就没保存)又删除,这种直接删除即可 因为数据库没保存这些数据[ { "addFlag": true, "shortPlayId": 8, "shortPlayName": "北京攸合" } ]
-->
<template><div>
<!--    {{tags}}--><el-tag v-for="(tag,index) in filteredTags" :key="index" closable @close="handleClose(index)">{{tag.shortPlayName}}</el-tag><el-select v-model="bindModel" filterable clearable value-key="id"  placeholder="请选择短剧合作方" size="small" style="margin-left: 5px;width: 150px"><el-option v-for="item in options" :key="item.id" :label="item.name" :value="item"></el-option></el-select><el-button type="primary" size="small" style="margin-left: 5px" @click="addClick">添加</el-button></div>
</template><script>
import * as mapRequest from "@/api/map";
export default {name: "ag-album-short-play-partner-v2",props:{tags:{type:Array,required:true,default:()=>{return [];}}},data() {return {bindModel:{},options:[],}},created() {this.getList();},methods: {getList(){this.options=JSON.parse('[{"id":8,"name":"北京攸合","createdAt":"2023-12-26 14:26:09","updatedAt":"2023-12-26 14:26:09"},{"id":9,"name":"网易","createdAt":"2024-01-03 10:13:37","updatedAt":"2024-01-03 10:13:37"}]');//这里是要请求后台数据的// mapRequest.findShortPlayList({},{}).then(res=>{//   this.options=res.data.data.records;// }).catch(err=>{//   this.$message.error(err.data.message);// })},handleClose(index){const tag=this.filteredTags[index];// console.log("-----",tag);if(tag==null){this.$message.error("删除错误!");return;}const originalIndex = this.tags.findIndex(t => t === tag);if (originalIndex !== -1 && this.tags[originalIndex].id ) {this.$set(this.tags[originalIndex], 'delFlag', true);this.$emit('input', this.tags);}else if (originalIndex !=-1 && (this.tags[originalIndex].id === null || this.tags[originalIndex].id === undefined)  ){this.tags.splice(originalIndex,1);}// this.$set(tag,'delFlag',true);// console.log("data",tag,",tags:",this.tags);// this.$emit('input',this.tags);},addClick(){// 请勿重复添加if(this.bindModel.id){// console.log("@@@",this.bindModel);let data=this.bindModel;this.tags.push({addFlag:true,shortPlayId:data.id,shortPlayName:data.name});// console.log("---",this.tags);this.$emit('input',this.tags);this.bindModel=null;return;}else{this.$message.warning("请选择合作方后再添加~");return;}},},computed: {filteredTags() {return this.tags.filter(tag => !tag.delFlag);}},watch: {},components: {},}
</script><style scoped></style>

最终就是外面的调用

<!--
用来写测试案例
-->
<template><div><ag-album-short-play-partner :short-plays="shortPlays"></ag-album-short-play-partner><ag-album-short-play-partner-v2 :tags="shortPlays"></ag-album-short-play-partner-v2></div></template><script>
import agAlbumShortPlayPartner from "@/views/longVideo/album/components/ag_album_short_play_partner";
import AgAlbumShortPlayPartnerV2 from "@/views/longVideo/album/components/ag_album_short_play_partner_v2";
export default {name:'videoDirUploadList',data(){return{data:{album:{}},shortPlays:[{"id":8,"albumId":44116442,"shortPlayId":9,"createdAt":"2024-01-04 15:50:59","updatedAt":"2024-01-04 15:50:59","shortPlayName":"网易","delFlag":"","addFlag":""}],}},created() {},methods:{},components:{AgAlbumShortPlayPartnerV2,agAlbumShortPlayPartner,}}
</script><style>
</style>

ok,本期结束,关注作者不迷路~持续更新好用的组件~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法每日一题:在链表中插入最大公约数 | 链表 | 最大公约数

hello&#xff0c;大家好&#xff0c;我是星恒 今天的题目是有关链表和最大公约数的题目&#xff0c;比较简单&#xff0c;核心在于求解最大公约数&#xff0c;我们题解中使用辗转相除法来求解&#xff0c;然后我们会在最后给大家拓展一下求解最大公约数的四个方法&#xff0c;…

vue3学习 【2】vite起步和开发工具基本配置

vite的简介 官方文档 刚起步学习&#xff0c;所以我们只需要按照官方文档的入门流程即可。推荐阅读一下官网的为什么使用vite vite目前需要的node版本是18&#xff0c;可以参考上一篇文章的安装nvm&#xff0c;用来进行多版本的node管理。 vite安装与使用 npm create vitela…

Android两个APP之间跳转+手机图标修改

APP之间跳转 两个APP之间跳转同样使用Intent进行跳转&#xff0c;将需要跳转的APP都下载到手机中&#xff0c;通过主APP调用需要跳转的APP包名进行跳转。 最好在其中加上try-catch语句&#xff0c;当需要跳转的APP不存在时进行错误抓取。 代码如下&#xff1a; Intent mInten…

MySQL索引简介(包含索引优化,索引失效,最左前缀简洁版)

一、索引的基本概念 1.什么是索引 索引是一种数据结构&#xff0c;用于快速查找和访问数据库中的数据。它类似于书本的目录&#xff0c;可以帮助数据库管理系统快速定位到存储数据的位置。通过创建索引&#xff0c;我们可以加快数据库的查询速度并提高系统的性能。索引可以基于…

Notepad++ v7.7.1 安装及添加插件

1、notepad_v7.7.1.zip npp.7.7.1.Installer.x64.exe npp.7.7.1.Installer.x86.exe notepad_v7.7.1.ziphttps://www.123pan.com/s/VTMXjv-X6H6v.html 2、notepad插件包_64bit_4.zip ComparePlugin ---->文件对比插件 ComparePlugin.dllNppFTP ---->FTP、FTPES和SFTP …

苹果Mac图像修图软件Photomator和Pixelmator Pro 有什么区别?

同为一个团队设计的Mac修图软件Photomator和Pixelmator Pro有哪些区别呢&#xff1f;有哪些不一样的功能&#xff1f; Photomator和Pixelmator Pro区别如下&#xff1a; 1、用途不同 Photomator 和 Pixelmator Pro 是两个功能强大的应用程序&#xff0c;具有两个不同的用途。…

第8课 将推流端与播放端合并为一对一音视频聊天功能

在第二章的第7课&#xff0c;我们实现了一个推流端&#xff0c;可以把音视频推送到rtmp服务器&#xff1b;在第一章的第4课&#xff0c;我们实现了一个播放器&#xff0c;可以正常播放rtmp音视频流。聪明的你应该可以想到了&#xff1a;把推流端和播放端合并在一起&#xff0c;…

宋仕强论道之华强北的劣势(十八)

华强北微观上的劣势。华强北的企业同质化严重&#xff0c;经营策略和定价方式都差不多&#xff0c;内卷现象突出&#xff0c;价格战、恶性竞争频发&#xff0c;小企业利润空间不断被挤压。如华强北的手机配件市场&#xff0c;很多商户销售相同品牌、相同型号的手机壳、充电器、…

10款以上开源工具,用于大型语言模型应用开发

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

intersection observer实现图片懒加载

图片懒加载&#xff08;Lazy Load&#xff09;是一种优化网页性能的技术&#xff0c;它可以延迟图片的加载时间&#xff0c;只有当用户滚动到该图片的位置时才会进行加载。这样可以减少页面的初始加载时间&#xff0c;提高页面的响应速度和用户体验。 以下是使用浏览器原生支持…

skimage图像处理(全)

文章目录 一、简介二、安装三、模块简介&#xff1a;API reference四、项目实战4.1、2D图像处理4.1.1、打印图像属性4.1.2、读取 / 显示 / 保存图像&#xff1a;skimage.io.imread() skimage.io.imshow() skimage.io.imsave()4.1.3、颜色空间转换&#xff1a;skimage.color.r…

LeetCode2807. Insert Greatest Common Divisors in Linked List

文章目录 一、题目二、题解 一、题目 Given the head of a linked list head, in which each node contains an integer value. Between every pair of adjacent nodes, insert a new node with a value equal to the greatest common divisor of them. Return the linked l…

2401d,d理解模板映射

原文 关于映射带模板参数的函数,我惊讶地发现它仍可同运行时确定的函数,甚至是闭包等工作.我想理解它背后的机制. 注释掉的行会导致错误,即编译时无法确定choice(funcs),这是公平的,但它为何与上面两行的func不一样?我猜是因为函数在编译时是可见的字面,但闭包使这可疑. impo…

Python画草莓熊

前言 今天&#xff0c;我们来画草莓熊。 一、草莓熊 草莓熊&#xff0c;英文名Lotso&#xff0c;迪士尼公司和皮克斯动画工作室公司于2010年合作推出的动画片《玩具总动员3》(Toy Story3)的反派角色。Lotso就是大受欢迎的反派"草莓熊"--这是一个特殊的角色&#x…

C#的StringBuilder方法

一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串&#xff08;包含零个或更多格式项&#xff09;而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…

计算机二级Python选择题考点——公共基础部分

计算机完成一条指令所花费的时间称为一个指令周期。(指令周期越短&#xff0c;指令执行就越快)顺序程序不具有并发性。(具有顺序性、封闭性和可再现性)结构化程序设计强调程序的易读性。系统软件&#xff1a;操作系统、编译程序、数据库管理系统 应用软件&#xff1a;杀毒软件在…

设置docker容器的时区

目录 基于Alpine镜像的Docker容器的Dockerfile中 基于dpkg包管理且使用APT的Linux发行版镜像的docker容器的Dockerfile中 基于Alpine镜像的Docker容器的Dockerfile中 # 替换国内源&#xff0c;可按需添加 RUN set -eux && sed -i s/dl-cdn.alpinelinux.org/mirrors.…

选择 省市区 组件数据 基于vue3 + elment-plus

h5 <el-cascader v-model"form.area" :props"{value: label,label: label }" :options"jsonData" change"handleChange" style"width: 100%;" /> script import jsonData from /utils/city.json; 选完省市区 数据是一…

iview inputNumber有一个默认值1,来看解决方案

iview inputNumber为什么总有一个默认值1&#xff0c;怎么让它为空。 修改编辑没问题&#xff0c;赋值都没问题&#xff0c;但是新增的时候会有默认值1&#xff0c;也没赋值 这种情况你要手动解决&#xff0c;看看当前值有没有被覆盖 我这个问题就是出现覆盖导致的 看代码似乎…

Linux 进程(十) 进程替换

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec*函数以执行另一个程序。当进程调用一种exec*函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec*并不创建新进程,所以调用exec*前…