Vue页面内公共的多类型附件图片上传区域并适用折叠面板

  • A+
所属分类:Web前端
摘要

在前端项目中,附件上传是很常用的功能,几乎所有的app相关项目中都会使用到,一般在选择使用某个前端UI框架时,可以查找其内封装好的图片上传组件,但某些情况下可能并不适用于自身的项目需求,本文中实现的附件上传区域支持超多类型附件分类型上传,并且可根据特定条件具体展示某些类型的附件上传,本文中是直接摘自具体的页面,后面会抽时间单独封装出来一个附件上传的组件。

在前端项目中,附件上传是很常用的功能,几乎所有的app相关项目中都会使用到,一般在选择使用某个前端UI框架时,可以查找其内封装好的图片上传组件,但某些情况下可能并不适用于自身的项目需求,本文中实现的附件上传区域支持超多类型附件分类型上传,并且可根据特定条件具体展示某些类型的附件上传,本文中是直接摘自具体的页面,后面会抽时间单独封装出来一个附件上传的组件。

 

一、Vue页面内附件展示区域代码

 1 <div class="retuinfo">  2           <div class="theadInfo-headline">  3             <span></span>  4             {{FileDivName}}  5           </div>  6           <Collapse v-model="defaultCollapse">  7             <Panel v-for="(item,pngIndex) in pngFileArray" v-bind:key="pngIndex" :name="item.num" v-show="item.isshow">  8               {{item.name}}  9               <div class="obsfilesdiv" slot="content"> 10                 <div v-for="(obs,index) in item.files" v-bind:key="index" class="obsfileslist"> 11                   <input ref="fileImg" type="file" accept="image/*;capture=camera" style="display: none;" 12                     @change="setObsFile(item.num,1,obs.FileType,obs.Num,obs.Code)"> 13                   <label style="color:#6d7180; font-size: 20px;">{{obs.FileType}}<span style="color:red;" 14                       v-show="obs.FileType!='其他'">*</span></label> 15                   <ul class="obsfilesul"> 16                     <li v-for="(objitem,objindex) in obs.FileObj" v-bind:key="objindex"> 17                       <img :src="objitem.imgurl ? objitem.imgurl : fileUrl" 18                         @click="showObsFiles(obs.FileFlag,objitem.imgurl)" /> 19                       <img src="../../../img/other/wrong.png" v-show="objitem.IsCanEdit" class="wrong_class" 20                         @click="deleteObsFlie(item.num,index,objindex,objitem.imgid,objitem.imgurl)" /> 21                     </li> 22                     <li style="border: 4px solid #f3f3f3;" @click="PlusClick(obs.FileType,obs.FileFlag,obs.Num)"> 23                       <img src="../../../img/icon-adds.png" alt="" /> 24                     </li> 25                     <div style="clear:both;"></div> 26                   </ul> 27                 </div> 28               </div> 29             </Panel> 30           </Collapse> 31         </div> 32         <div class="modal" v-show="viewBigImg"> 33             <div class="img-view-modal" style="text-align: right;"> 34                 <img :src="viewImgURL" style="width: 100%;" @click="hideShow(0)"> 35                 <Icon type="md-close" style="margin-right: 20px;" size='20' @click="hideShow(0)" /> 36             </div> 37         </div> 38       </div>

Vue项目引入了以下UI框架:(若想拿来即用 需要先在main.js中引入)
IView、MintUI、Vant 此段代码只要确保引入IView即可正常使用

二、数据绑定设计

具体的不详细展开说,数组与通过属性控制,很好理解。

pngFileArray: [{             num: '0',             name: '整车',             isshow: localStorage.getItem("RoleName").indexOf('铭牌质检员') != -1 ? true : false,             files: [ //FileFlag://1:图片;2:视频  3.其他               {                 FileType: '整车铭牌图片',                 Code: '201',                 Num: 0,                 FileFlag: 1,                 FileObj: [],                 IsNoFile: true               },               {                 FileType: '车架VIN图片',                 Code: '207',                 Num: 1,                 FileFlag: 1,                 FileObj: [],                 IsNoFile: true               },               {                 FileType: '终端图片',                 Code: '301',                 Num: 2,                 FileFlag: 1,                 FileObj: [],                 IsNoFile: true               }             ]           },           {             num: '1',             name: '里程',             isshow: localStorage.getItem("RoleName").indexOf('客户经理') != -1 ? true : false,             files: [{                 FileType: '里程表照片',                 Code: '701',                 Num: 3,                 FileFlag: 1,                 FileObj: [],                 IsNoFile: true               }             ]           }         ],

 

三、绑定的方法

1.图片加载方法:

 1 //获取图片列表  2       getImageList() {  3         this.$indicator.open({  4           text: '图片加载中...',  5           spinnerType: 'snake'  6         });  7         let _this = this;  8         let downRequest ={  9             'crm_vin': this.parms.crm_vin, 10             'crm_vehiclenumber': this.parms.crm_vehiclenumber 11           }; 12         let imgListParams = { 13           "ImageDownRequest": JSON.stringify(downRequest), 14           "username": localStorage.getItem("usernameone"), 15           "password": localStorage.getItem("password") 16         }; 17         console.log("获取图片列表参数:", imgListParams); 18         _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头 19         this.$ajax.post(this.imageListUrl, this.$qs.stringify(imgListParams)).then(resdata => { 20           _this.$indicator.close(); 21           console.log("获取到的图片列表数据:", resdata); 22           let data = resdata.data; 23           console.log("转换后的图片列表数据:", data); 24           if (resdata.status != 200) { 25             _this.$toast({ 26               message: '获取图片列表失败!', 27               duration: 3000 28             }); 29             return; 30           } 31           //先清空原有的图片列表 32           _this.pngFileArray.forEach((rr,index,array) =>{ 33             for(var file=0;file<rr.files.length;file++){ 34               _this.pngFileArray[index].files.FileObj = []; 35               _this.pngFileArray[index].files.IsNoFile = true; 36             } 37           }); 38           //将图片列表写入页面各图片分类区域 39           for(var i=0;i<data.length;i++){ 40             _this.pngFileArray.forEach((rr,index,array) =>{ 41               for(var file=0;file<rr.files.length;file++){ 42                 if(data[i].crm_imagetypeno==rr.files.Code){ 43                   let putparm = { 44                     "IsCanEdit":false, 45                     "imgid": data[i].crm_careimageId, 46                     "imgurl": data[i].ImageUrl 47                   }; 48                   _this.pngFileArray[index].files.FileObj.push(putparm); 49                   _this.pngFileArray[index].files.IsNoFile = false; 50                 } 51               } 52             }); 53  54           } 55         }).catch(function(error) { 56           _this.$indicator.close(); 57           _this.$toast({ 58             message: error, 59             duration: 3000 60           }); 61         }); 62       },

 

2.图片展示方法

showObsFiles(type, url) { //展示图片或视频         console.log("展示附件:" + type);         if (type == 1) { //图片           this.viewBigImg = true;           this.viewImgURL = url;         } else { //文件           this.$messagebox.alert("不支持查看文件,请到PC端操作!", "提示");           return;         }       },

 

3.上传图片相关方法 

(最开始设计的是支持图片、视频和其他类型文件等上传,项目中已实现,本文中不做拓展)

  1 PlusClick(type, flag, num) {   2         console.log("当前附件类型:" + type);   3         console.log("当前附件序号:" + num);   4         this.currentFileType = type;   5         if (flag == 1) { // 图片上传   6           this.$refs.fileImg[num].dispatchEvent(new MouseEvent('click'));   7         } else if (flag == 2) { // 视频上传   8           this.$refs.fileVideo[num].dispatchEvent(new MouseEvent('click'));   9         } else { // 其他类型文件  10           this.$refs.filElem[num].dispatchEvent(new MouseEvent('click'));  11         }  12       },  13 setObsFile(classify, type, obsFileType, num, code) { //保存图片到crm中  14         var _this = this;  15         var inputFile; //文件流  16         console.log("图片大分类:" + classify + " " + obsFileType + " " + num) + " 图片编码:" + code;  17         if (type == 1) {  18           inputFile = this.$refs.fileImg[num].files[0];  19           this.$refs.fileImg[num].value = '';  20         }  21         var fileName = inputFile.name;  22         if (!inputFile) {  23           return;  24         }  25         if (inputFile.type == 'image/jpg' || inputFile.type == 'image/jpeg' || inputFile.type == 'image/png' ||  26           inputFile.type ==  27           'image/gif') {} else {  28           this.$messagebox.alert("请上传图片", "提示");  29           return;  30         }  31         _this.$indicator.open({  32           text: '文件上传中,请稍候...',  33           spinnerType: 'snake'  34         });  35         //图片压缩与转换成base64文件流  36         var reader = new FileReader();  37         reader.readAsDataURL(inputFile);  38         reader.onloadend = function(e) {  39           let result = this.result;  40           console.log('********未压缩前的图片大小******** :' + result.length / 1024)  41           _this.pulic.dealImage(result, {}, function(base64) {  42             console.log('********压缩后的图片大小******** :' + base64.length / 1024)  43             _this.putObsFile(classify, fileName, base64, obsFileType, code);  44           });  45           //reader.result.substring(this.result.indexOf(',')+1);  46           // 'data:image/png;base64,'+reader.result  47         }  48       },  49       putObsFile(classify, fileName, base64, obsFileType, code) { //抽出公共上传图片文件方法  50         var _this = this;  51         let usernameone = this.$Base64.encode("administrator");  52         let password = this.$Base64.encode("pass@word1");  53         let parmsImages = {  54           crm_newenergyid: localStorage.getItem("crm_newenergyid"),  55           vin: _this.parms.crm_vin,  56           crm_vehiclenumber: _this.parms.crm_vehiclenumber,  57           CareType: code,  58           CreateBy: localStorage.getItem("SystemUserId"),  59           ImageStr: base64.split(",")[1],  60           username: usernameone,  61           password: password  62         }  63         let parms = {  64           ImageMessage: JSON.stringify(parmsImages)  65         }  66         console.log(JSON.stringify(parmsImages));  67         console.log(JSON.stringify(parms));  68         _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头  69         _this.$ajax.post(_this.imageSaveUrl, _this.$qs.stringify(parms))  70           .then(resdata => {  71             _this.$indicator.close();  72             console.log("接口响应数据:", resdata);  73             let data = resdata.data;  74             console.log("转换后的响应数据:", data);  75             if (resdata.status != 200) {  76               _this.$toast({  77                 message: '保存失败!接口调用异常',  78                 duration: 3000  79               });  80               return;  81             }  82             //将上传成功后的图片url回写到页面的图片分类url中  83             console.log("当前分类下的所有图片类型:" + JSON.stringify(_this.pngFileArray[parseInt(classify)].files));  84             for (var i = 0; i < _this.pngFileArray[parseInt(classify)].files.length; i++) { //遍历当前分类下的图片类型数组  并赋值后台返回的数据  85               if (obsFileType == _this.pngFileArray[parseInt(classify)].files[i].FileType) {  86                 //设置图片文件路径等 putparm  87                 let putparm = {  88                   "IsCanEdit":true,  89                   "imgid": data.crm_careimageId,  90                   "imgurl": data.ImageUrl  91                 };  92                 _this.pngFileArray[parseInt(classify)].files[i].FileObj.push(putparm);  93                 _this.pngFileArray[parseInt(classify)].files[i].IsNoFile = false;  94               }  95             }  96             _this.$messagebox.alert("附件上传成功", "提示");  97           }).catch(err => {  98             console.log(JSON.stringify(err));  99             _this.$toast({ 100               message: '上传失败', 101               duration: 1500 102             }); 103             _this.$indicator.close(); 104           }); 105       },


 

 

4.删除图片方法

(本文中是只有未提交的图片可删除,若已提交过的图片即页面初始加载获取到的图片不可以删除)

 1 deleteObsFlie(classify,num,index,id,url) { //删除附件  2         var _this = this;  3         this.$messagebox.confirm('确定删除该图片吗?', "确认").then(action => {  4           var del_param = {  5             "id": id,  6             "url": url  7           };  8           _this.$indicator.open({  9             text: '删除图片中,请稍候...', 10             spinnerType: 'snake' 11           }); 12           _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头 13           _this.PromiseCall(_this.DelImgFilesURL, _this.$qs.stringify(del_param)) 14             .then(data => { 15               _this.$indicator.close(); 16               console.log(JSON.stringify(data)); 17               if (data.status != 200) { 18                _this.$messagebox.alert("删除图片失败", "提示"); 19                return; 20               } 21               _this.pngFileArray[parseInt(classify)].files[num].FileObj.splice(index, 1); 22               _this.$toast({ 23                 message: '删除图片成功', 24                 duration: 1500 25               }); 26             }).catch(err => { 27               _this.doCatch(err); 28               _this.$toast({ 29                 message: '删除图片失败'+err, 30                 duration: 1500 31               }); 32               _this.$indicator.close(); 33             }); 34         }); 35       },

 

四、CSS样式

Vue页面内公共的多类型附件图片上传区域并适用折叠面板Vue页面内公共的多类型附件图片上传区域并适用折叠面板

.retuinfo {     width: 96%;     height: auto;     margin-top: 20px;     margin-left: 2%;     background-color: #F5F7FA;     border-radius: 15px;   } .theadInfo-headline {     width: 100%;     height: 80px;     background: #F3F3F3;     display: flex;     padding-left: 30px;     align-items: center;     font-size: 28px;     color: #666666;     border-radius: 15px;   }   .theadInfo-headline span {     width: 6px;     height: 32px;     background: #5576AB;     border-radius: 3px;     margin-right: 10px;   } .ivu-collapse-header {     height: 40px;     align-items: center;     display: flex;   } .obsfilesdiv {     width: 100%;     height: auto;     margin-top: .5rem;     margin-bottom: 50px; } .obsfileslist {     width: 100%;     height: auto;     padding: 0.5rem 0.5rem;     background: #fff; } .obsfilesul {     width: 100%;     height: auto;     padding-bottom: 8px; } .obsfilesul li {     width: 120px;     height: 120px;     float: left;     margin-top: .3rem;     overflow: hidden;     margin-right: .3rem;     border: none; } .obsfilesul li img {     width: 100%;     height: 100%; } .imglist {     width: 100%;     margin-top: .5rem;     margin-bottom: 6rem; } .modal {     background-color: #A9A9A9;     position: fixed;     z-index: 99;     left: 0;     top: 0;     width: 100%;     height: 100%;     padding-top: 4rem;     /*opacity: 0.5;*/     align-items: center;     /*定义body的元素垂直居中*/     justify-content: center;     /*定义body的里的元素水平居中*/ } .modal img {     animation-name: zoom;     animation-duration: 0.6s;     display: block;     padding: 10px;     margin: auto;     max-width: 100%;     max-height: 100%;     box-shadow: 0 2px 6px rgb(0, 0, 0, 0), 0 10px 20px rgb(0, 0, 0, 0);     border-radius: 12px;     border: 1px solid white;     position: absolute;     top: 50%;     transform: translateY(-50%); } .showname {     width: 100px;     height: 60px;     position: relative;     top: -4.5rem;     white-space: normal;     word-break: break-all;     word-wrap: break-word; } .wrong_class {     width: 30% !important;     height: 30% !important;     position: relative;     top: -3.8rem;     left: 2.6rem; } .wrongs_class {     width: 4% !important;     height: 4% !important;     position: relative;     /*top: -5.2em;*/     left: 0.5rem; }

View Code

 

最后附上实际效果图:

Vue页面内公共的多类型附件图片上传区域并适用折叠面板

Vue页面内公共的多类型附件图片上传区域并适用折叠面板

 

 

Vue页面内公共的多类型附件图片上传区域并适用折叠面板