阅读 135

Element Tag 标签

前言

这篇文章主要是记录一下,我在用tag标签的时候遇到的一些问题,因为是后端管理系统中的标签管理页面,所以只有基本的增删改查功能。。。,好了,废话不多说了,直接开始

Tag标签

因为需要进行标签的更改,所以直接使用Tag标签里面的动态编辑标签,直接把代码拿过来用

<el-tag   :key="tag"   v-for="tag in dynamicTags"   closable   :disable-transitions="false"   @close="handleClose(tag)">   {{tag}} </el-tag> <el-input   class="input-new-tag"   v-if="inputVisible"   v-model="inputValue"   ref="saveTagInput"   size="small"   @keyup.enter.native="handleInputConfirm"   @blur="handleInputConfirm" > </el-input> <el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button> <style> .el-tag + .el-tag {   margin-left: 10px; } .button-new-tag {   margin-left: 10px;   height: 32px;   line-height: 30px;   padding-top: 0;   padding-bottom: 0; } .input-new-tag {   width: 90px;   margin-left: 10px;   vertical-align: bottom; } </style> <script> export default {   data() {     return {       dynamicTags: ["标签一", "标签二", "标签三"],       inputVisible: false,       inputValue: "",     };   },   methods: {     handleClose(tag) {       this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);     },     showInput() {       this.inputVisible = true;       this.$nextTick((_) => {         this.$refs.saveTagInput.$refs.input.focus();       });     },     handleInputConfirm() {       let inputValue = this.inputValue;       if (inputValue) {         this.dynamicTags.push(inputValue);       }       this.inputVisible = false;       this.inputValue = "";     },   }, }; </script> 复制代码

这样就直接拥有了一个基本Tag标签页面

image.png

调取数据获取接口

调取自己封装好的数据接口,拿取后端返回的数据。。。。,在我看到到后端返回我的数据格式,我就知道这个页面之后的增删改查功能将会不是太好实现。。。,数据长成这样。。。。

image.png

看到数据的不断嵌套,我就感觉自己头已经有点大了。。。,啥也不说了,直接调取接口拿到数据:

       //获取数据     getdata() {       getwarninglabel({         pageNum: this.pageNum,         pageSize: this.pageSize,       }).then((res) => {         console.log(res);         this.total = res.data.count; //分页         this.tagtitle = res.data.results; //总数据       });     }, 复制代码

进行数据获取,而要获取标签的数据keywords,需要进行两层的嵌套循环,第一层遍历,通过item.keywords拿到每一个keywords的数据,之后再遍历item.keywords,来循环keywords里面的数据,代码如下:

<div v-for="(item, ki) in tagtitle" :key="ki" class="text item">       <el-card>         <div slot="header">           <span> {{ item.label_name }}</span> //标签标题                   </div>         <div>           <el-tag             :key="indext"             //遍历循环item.keywords,拿到标签数据             v-for="(tag, indext) in item.keywords"              :disable-transitions="false"             closable              @close="handleClose(tag)"           >             {{ tag }}           </el-tag> 复制代码

image.png

此时已经完成了页面数据的基本渲染,之后开始添加其他的功能

按钮添加

按照需求,需要在点击编辑按钮时,tag标签后面才会出现删除图标,同时编辑按钮变成保存提交按钮,因而需要对删除图标是否出现以及编辑/保存按钮的切换进行处理

  1. 添加编辑/保存以及模块删除按钮

<el-button             @click="hangdelDelete(item.id)"             style="float: right; padding: 3px 0; color: red"             type="text"             >删除</el-button           >           <el-button             v-show="activeIndex != ki"             @click="handelUpdata(item.id, ki)"             style="float: right; padding: 3px 0"             type="text"             >编辑</el-button           >           <el-button             v-show="activeIndex === ki"             @click="handelUpdatat(item.id, ki)"             style="float: right; padding: 3px 0"             type="text"             >保存</el-button           > 复制代码

image.png

2.控制tag标签的删除按钮是否出现 我是直接删除了tag标签自带的删除图标,也就是closable,之后自己在后面添加了一个icon图标,通过v-show来判断是否显示

<el-tag             :key="indext"             v-for="(tag, indext) in item.keywords"             :disable-transitions="false"           >             {{ tag }}             <i               v-show="activeIndex === ki"               class="el-icon-circle-close"               @click="handleClose(tag,indext)"             ></i>           </el-tag> 复制代码

结果如下:

image.png

遇到问题

此时已经写好了编辑/保存,删除按钮以及tag标签的删除图标,而且对它们是否显示也进行了判断,但是此时就遇到了第一个问题,也就是在点击编辑按钮时,所有的tag标签后面都出现了icon图标,同时所有的编辑按钮也变成了保存,问题展示如下:

image.png

image.png

此时,需要处理的是,如何实现点击哪一个标签模块,哪一个便签模块进行改变,而不是全部发生改变,解决办法如下:

一、定义一个字段,并给它一个初始化的值,如-1,因为index排序从0开始,所以不能赋值为0  activeIndex: -1,  二、将v-show是否显示的true/false判断,改成通过点击时将获取的index值赋值给activeIndex之后和index的值来进行判断,相等即为true,进行展示,不相等极为false,不进行展示 复制代码

代码如下:

<div v-for="(item, ki) in tagtitle" :key="ki" class="text item">  <el-button             @click="handelUpdata(item.id, ki)" //拿取渲染排序的值             style="float: right; padding: 3px 0"             type="text"             >编辑</el-button           >       //方法         handelUpdata(id, ki) { //ki index排序          console.log(id);          console.log(ki);           this.activeIndex = ki; //将排序值赋值给activeIndex       }       //使用        <i               v-show="activeIndex === ki" //即可进行是否显示判断               class="el-icon-circle-close"               @click="handleClose(tag,indext)"             ></i> 复制代码

实现功能如下:

image.png

删除功能

模块的删除功能比较简单,直接通过后端给的模块id,通过id传递给后端即可,这里主要解决的是,tag标签的删除,这些标签没有id存在,打开 Tag标签,查看一下删除功能的实现:

image.png 直接使用这个方法,但是会突然发现,后端返回的数据格式和需要的数据格式不同:

Element UI数据格式:

image.png

后端返回的数据格式:

image.png

也就是说如果使用Element UI自带的方法,那么就需要使用和它一样的数据格式,也就是相当于results[0].keywords里面的数据,如下:

image.png

通过这种比较,很容易想到通过模块的index值,在点击时,将index的值放到results[].keywords中,即可拿到每一个keywords中的数据,之后放到新定义的数组中,即可使用tag标签自带的方法:

this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1); 实现代码如下:

一、定义一个新数组

 deleIndex: [], 复制代码

二、定义一个新的字段来获取模块的index值

  numberid: "", 复制代码

三、拿取index值并赋值给 numberid

//编辑 handelUpdata(id, ki) { //ki index排序     this.activeIndex = ki;     this.numberid = ki; //获取index值     } 复制代码

四、将numberid放入到results[].keywords,即可拿取到keywords中的数据,并放到deleIndex

//获取数据  getdata() {    getwarninglabel({      pageNum: this.pageNum,      pageSize: this.pageSize,    }).then((res) => {      console.log(res);      this.total = res.data.count;      this.tagtitle = res.data.results;       console.log(res.data.results[0].keywords);       console.log(res.data.results[this.numberid].keywords);       console.log(res.data.results[this.numberid].label_name);       this.deleIndex = res.data.results[this.numberid].keywords; //赋值       this.deletitle = res.data.results[this.numberid].label_name;        });  }, 复制代码

五、使用tag标签自带的删除方法

//删除方法     handleClose(tag, indext) {         console.log(indext)          this.deleIndex.splice(this.deleIndex.indexOf(tag), 1);     }, 复制代码

标签删除功能实现:

image.png

新增功能

新增功能实现也比较简单,唯一的麻烦就是如何将输入的字符串格式的数据转化成数组,同时将新增的标签数据与其他没有改变的数据进行合并,也就是将两个数组进行合并:、

1、新增数据格式:

image.png

name的值取出来,放到一个数组中,即可生成后端需要的数据格式,代码如下:

//新建数组,获取新增的数据 mileEdit:[] //进行数据处理  this.mileEdit = this.ruleForm.options;       console.log(this.mileEdit);       //定义一个新数组来存放处理后的数据       const eddvalue = this.mileEdit.map((value) => {          return value.name;       }); 复制代码

2、处理后结果如下:

image.png

3、将新增的数据与没有改变的数据一起给后端传递过去,即新增数组与原来的数组进行合并,通过concat来实现数组的合并,代码如下:

 titleEdit(id,{         label_name: this.deletitle,         keywords: eddvalue.concat(this.deleIndex) ,//数组合并       }).then((res) => {         console.log(res);         this.$message({           message: "新增成功!",           type: "success",         }); 复制代码

即完成了标签的增加功能

完整代码:

<template>   <div>     <el-button type="primary" @click="Addmunu()">新增主类</el-button>     <div v-for="(item, ki) in tagtitle" :key="ki" class="text item">       <el-card>         <div slot="header">           <span> {{ item.label_name }}</span>           <el-button             @click="hangdelDelete(item.id)"             style="float: right; padding: 3px 0; color: red"             type="text"             >删除</el-button           >           <el-button             v-show="activeIndex != ki"             @click="handelUpdata(item.id, ki)"             style="float: right; padding: 3px 0"             type="text"             >编辑</el-button           >           <el-button             v-show="activeIndex === ki"             @click="handelUpdatat(item.id, ki)"             style="float: right; padding: 3px 0"             type="text"             >保存</el-button           >         </div>         <div>           <el-tag             :key="indext"             v-for="(tag, indext) in item.keywords"             :disable-transitions="false"           >             {{ tag }}             <i               v-show="activeIndex === ki"               @click="handleClose(tag,indext)"             ></i>           </el-tag>           <span v-show="activeIndex === ki">             <el-form :inline="true" :model="ruleForm" ref="ruleForm">               <el-form-item                 v-for="(item, index) in ruleForm.options"                 :key="index"               >                 <el-row>                   <el-col :span="4">                     <el-input                       clearable                       style="width: 200px"                       v-model="item.name"                       placeholder="请输入标签名"                     ></el-input>                   </el-col>                   <!-- <el-col :span="8">                 <el-button type="danger" plain @click="deleteOption(index)"                   >删除选项</el-button                 >               </el-col> -->                 </el-row>               </el-form-item>               <el-button  type="primary" plain @click="addOption(index)"                 >新增标签</el-button               >             </el-form>           </span>         </div>       </el-card>     </div>     <!-- 分页 -->     <pagination       v-show="total > 0"       :total="total"       :page.sync="pageNum"       :limit.sync="pageSize"       @pagination="getdata"     />     <!-- 新增主类弹窗 -->     <el-dialog title="添加标签" :visible.sync="dialogruleForm4Visible">       <el-form         :model="ruleForm4"         ref="ruleForm4"         label-width="100px"       >         <el-form-item label="标签主类" prop="title">           <el-input v-model="ruleForm4.title"></el-input>         </el-form-item>         <template>           <el-form-item             :label="'标签' + (index + 1)"             v-for="(item, index) in ruleForm4.options"             :key="index"           >             <el-row>               <el-col :span="16">                 <el-input                   v-model="item.name"                   placeholder="请输入标签名"                   style="width: 90%"                 ></el-input>               </el-col>               <el-col :span="8"> </el-col>             </el-row>           </el-form-item>           <el-button             type="primary"             style="float: left"             plain             @click="addppOption"             >新增标签</el-button           >         </template>         <el-form-item> </el-form-item>       </el-form>       <div slot="footer">         <el-button @click="dialogruleForm4Visible = false">取 消</el-button>         <el-button type="primary" @click="checkAddppQuestion()"           >确 定</el-button         >       </div>     </el-dialog>   </div> </template> <script> import {   getwarninglabel,   hangdleadd,   deletedata,titleEdit } from "@/api/label/riskwarning"; export default {   data() {     return {       // 分页       total: "",       pageNum: 1,       pageSize: 10,       //题目排序       numberid: "",       deleteadd:"",       isShow:false,       deleIndex: [],       deletitle: "",       activeIndex: -1,       tagtitle: [], //标签题目       milepost: [],//新增数据处理       mileEdit: [],//修改数据处理       tagclosable: false,       dynamicTags: ["标签一", "标签二", "标签三"],       inputVisible: false,       inputValue: "",       //添加标签       ruleForm: {         options: [           {             name: "", //标签           },         ],       },       //添加主类       ruleForm4: {         title: "", //主类         options: [           {             name: "", //标签           },         ],       },       dialogruleForm4Visible: false,     };   },   methods: {     //添加添加标签     addOption(index) {       this.ruleForm.options.push({         name: "",       });      this.deleteadd = index       console.log(888777)     },     getdelete(){         console.log(99999)          this.ruleForm.options.splice(this.deleteadd, 1);     },           //添加添加标签     addppOption() {       this.ruleForm4.options.push({         name: "",       });     },     //新增主类     Addmunu() {       this.dialogruleForm4Visible = true;     },     //新增     checkAddppQuestion() {       console.log(this.ruleForm4.options);       this.milepost = this.ruleForm4.options;       console.log(this.milepost);       const checker = this.milepost.map((value) => {         return value.name;       });       console.log(checker);       hangdleadd({         label_name: this.ruleForm4.title,         keywords: checker,       }).then((res) => {         console.log(res);         this.$message({           message: "新增成功!",           type: "success",         });         this.ruleForm4 = {           id: 0,           title: "",           options: [""],         };         this.getdata();       });       this.dialogruleForm4Visible = false;     },     //标签新增          //获取数据     getdata() {       getwarninglabel({         pageNum: this.pageNum,         pageSize: this.pageSize,       }).then((res) => {         console.log(res);         this.total = res.data.count;         this.tagtitle = res.data.results;          console.log(res.data.results[0].keywords);           console.log(this.numberid);          console.log(res.data.results[this.numberid].keywords);          console.log(res.data.results[this.numberid].label_name);          this.deleIndex = res.data.results[this.numberid].keywords;          this.deletitle = res.data.results[this.numberid].label_name;          console.log(this.deleIndex)       });     },     //编辑     handelUpdata(id, ki) {       //ki index排序       console.log(id);       console.log(ki);       this.activeIndex = ki;       this.numberid = ki;             this.ruleForm = {           id: 0,           options: [""],         };          this.getdata();         //  this.addOption();         this.getdelete();     },     //保存     handelUpdatat(id, ki) {       console.log(id);       console.log(ki);       this.activeIndex = -1;        console.log(this.ruleForm.options);       this.mileEdit = this.ruleForm.options;       console.log(this.mileEdit);       const eddvalue = this.mileEdit.map((value) => {         return value.name;       });       console.log(eddvalue)        titleEdit(id,{         label_name: this.deletitle,         keywords: eddvalue.concat(this.deleIndex) ,       }).then((res) => {         console.log(res);         this.$message({           message: "新增成功!",           type: "success",         });         this.ruleForm = {           options: [""],         };         this.getdata();       });      this.getdata();           },     //删除主模块     hangdelDelete(id) {       this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {         confirmButtonText: "确定",         cancelButtonText: "取消",         type: "warning",         center: true,       })         .then(() => {           deletedata(id).then((res) => {             console.log(res);             this.$message({               type: "success",               message: "删除成功!",             });             this.getdata();           });         })         .catch(() => {           this.$message({             type: "info",             message: "已取消删除",           });         });     },     //删除方法     handleClose(tag, indext) {         console.log(indext)         // this.deleIndex.splice(indext, 1);          this.deleIndex.splice(this.deleIndex.indexOf(tag), 1);     },   },   mounted() {          console.log(88888);     this.getdata();   }, }; </script> <style  scoped> /* 卡片 */ .item {   margin-bottom: 18px; } .clearfix:before, .clearfix:after {   display: table;   content: ""; } .clearfix:after {   clear: both; } .box-card {   width: 100%; } /* 标签 */ .el-tag + .el-tag {   margin-left: 10px; } .button-new-tag {   margin-left: 10px;   height: 32px;   line-height: 30px;   padding-top: 0;   padding-bottom: 0; } .input-new-tag {   width: 90px;   margin-left: 10px;   vertical-align: bottom; } </style>


作者:月__
链接:https://juejin.cn/post/7023659140253909029


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐