Vue頁面內公共的多型別附件圖片上傳區域並適用摺疊皮膚

流浪阿丁發表於2021-12-23

在前端專案中,附件上傳是很常用的功能,幾乎所有的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[file].FileObj = [];
35               _this.pngFileArray[index].files[file].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[file].Code){
43                   let putparm = {
44                     "IsCanEdit":false,
45                     "imgid": data[i].crm_careimageId,
46                     "imgurl": data[i].ImageUrl
47                   };
48                   _this.pngFileArray[index].files[file].FileObj.push(putparm);
49                   _this.pngFileArray[index].files[file].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頁面內公共的多型別附件圖片上傳區域並適用摺疊皮膚
.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

 

最後附上實際效果圖:

 

 

 

 

 

 

 

相關文章