vue + 原生input 框上傳多張圖片

sunny_lss發表於2019-04-08

給的設計稿樣式和element ui 很不一樣 雖然一直堅信 沒有覆蓋不了的樣式 但這次自己用原生的寫了一次 爬坑之路繼續中....

要求: 一次上傳多張圖片限制一次最多4張 對每一張圖片可以單獨修改 點選加號 產生一個可以上傳多個圖片的結構 最多限制五組

1 html 程式碼 

        <div class="wrapIntroduction">
              <div class="wrapTop">
                <span class="modelPhoto">
                  <i class="warnImg"></i> 簡介:
                </span>
                <span class="tips">
                  <i class="tipImg"></i> 單條最多支援4張圖片,格式為JPG/PNG 圖片不大於1M,建議尺寸650*350畫素.
                </span>
              </div>
              <div class="wrapContent" v-for="(item,i) in introducList" :key="i">
                <textarea v-model="item.describe" class="describe" maxlength="400"></textarea>
                <button class="addButton" @click="addDes(i,$event)">+</button>
                <button class="reduceButton" v-show="i > 0" @click="removeDes(i,$event)">-</button>
                <label class="updateImg">
                  上傳圖片
                  <input
                    @change="onModelImg(i,$event,-1)"
                    multiple="multiple"
                    accept="image/jpeg, image/jpg, image/png"
                    type="file"
                    ref="updateImg"
                  >
                </label>
                <ul class="modelDetail" v-if="item.isShow">
                  <div class="modelDiv" v-for="(ite,ind) in item.imgs" :key="ind">
                    <li class="everyModel" v-if="!ite.isDelete">
                      <div class="deleteDiv">
                        <img class="deleteImg" @click="deleteModel(i,ind)" :src="deleteImg" alt>
                      </div>
                      <label>
                        <div class="modifyImg">
                          <p>修 改</p>
                          <input type="file" @change="onModelImg(i,$event,ind)">
                        </div>
                        <img class="detailImg" :src="ite.base" alt>
                      </label>
                    </li>
                  </div>
                </ul>
              </div>
             </div>

2  js 程式碼  

 資料結構 :

  確定imgs 陣列裡沒有被刪除的圖片有幾個 

forModelImg(arr) {
      arr = arr || [];
      var list = [];
      for (var i = 0; i < arr.length; i++) {
        let item = arr[i];
        if (!item.isDelete) {
          list.push(item.url);
        }
      }
      return list;
},

 

    onModelImg(index, e, appendTo) {
      // 監聽對應的input 框的改變事件 上傳簡介的圖片  -1   index
      var obj = this.introducList[index]; // 獲取陣列裡對應的物件
      obj.isShow = true;

      var input = e.target.cloneNode(true);
      e.target.value = ""; // 獲取當前點選的
      var fileResault = input.files;

      if (appendTo < 0) {
        var maxLen = 4;
        var oldLen = this.forModelImg(this.introducList[index]["imgs"]).length;
        var missLen = maxLen - oldLen;
        // console.log(maxLen,oldLen,missLen,fileResault.length)
        // 迴圈取出 每一個檔案  限制4 個
        if (fileResault && fileResault.length > missLen) {
          this.$message.warning("請每條描述至多新增" + maxLen + "張圖片");
        }
        for (var i = 0; i < fileResault.length && i < missLen; i++) {
          if (typeof fileResault[i] == "object") {
            this.uploadModel(obj["imgs"], fileResault[i], appendTo);
          }
        }
      } else {
        this.uploadModel(obj["imgs"], fileResault[0], appendTo);
      }
    },
    uploadModel(imgs, fileResault, appendTo) {
      // 上傳簡介的圖片
      var fileSize = fileResault.size;
      if (fileSize > 1024 * 1024) {
        // 圖片大小不要大於1M
        this.$message({
          message: this.$infoMsg.UPLOAD_IMG_ERROR,
          type: "warning"
        });
        return;
      }
      var fileType = fileResault.type;
      if (
        fileType != "image/jpeg" &&
        fileType != "image/jpg" &&
        fileType != "image/png"
      ) {
        this.$message({
          message: "請選擇正確型別的圖片",
          type: "warning"
        });
        return;
      }
      var reader = new FileReader();
      reader.readAsDataURL(fileResault);
      reader.onload = e => {
        var newObj = { base: "", url: "", isDelete: false }; 
         //{base:"",url:"",isDelete:false}
        newObj.base = e.target.result;
        // obj["imgs"].push(newObj);
        if (appendTo >= 0) {
          imgs.splice(appendTo, 1, newObj);
        } else {
          imgs.push(newObj);
          appendTo = imgs.length - 1;
        }
        //  把所有選中的圖片放到上傳處
        this.uploadModelImg(fileResault, imgs, appendTo)
          .then(function() {})
          .catch(() => {});
      };
    },
    async uploadModelImg(fileResault, imgs, appendTo) {
      let param = new FormData();
      param.append("Content", fileResault);
      param.append("SrvType", "mp");
      param.append("FileType", "uploademodelimg");
      this.$Api
        .uploadImg(param)
        .then(res => {
          var status = res.data.Code;
          if (status === 0) {
            // console.log(res.data.FilerPath);
            imgs[appendTo].url = res.data.FilerPath;
          }
        })
        .catch(err => {});
    },
    deleteModel(index, ind) {
      // 刪除模型詳情的對應的圖片 應該把對應的上傳的圖片刪除
      var obj = this.introducList[index];
      //   把對應的isDelete 調整為 true
      obj["imgs"][ind].isDelete = true;
      let count = 0;
      for (var i = 0; i < obj["imgs"].length; i++) {
        if (obj["imgs"][i].isDelete) {
          count++;
        }
      }
      if (count == obj["imgs"].length) {
        obj.isShow = false;
      }
    },
    addDes(index, e) {
      // 點選 增加模型描述和圖片 增加對應陣列裡的元素
      this.onStopPropagation(e);
      if (this.introducList.length < 5) {
        let obj = { describe: "", imgs: [], isShow: false };
        this.introducList.splice(index + 1, 0, obj);
      } else {
        //  最多可新增5條描述
        this.$message({
          message: this.$infoMsg.UPLOAD_DESCRIPTION_ERROR,
          type: "warning"
        });
        return;
      }
    },
    removeDes(index, e) {
      // 點選刪除 刪除對應的 新增的描述
      this.onStopPropagation(e);
      this.introducList.splice(index, 1);
    },

 css 樣式 

 .wrapContent {
          padding-left: 106px;
          position: relative;
          padding-bottom: 10px;
          .describe {
            text-indent: 20px;
            padding: 5px;
            width: 500px;
            height: 90px;
            line-height: 22px;
            border: 1px solid rgba(221, 221, 221, 1);
            border-radius: 3px;
            font-size: 14px;
            font-family: SourceHanSansCN-Regular;
            font-weight: 400;
            color: rgba(51, 51, 51, 1);
          }
          .addButton {
            width: 30px;
            height: 30px;
            background: rgba(246, 246, 246, 1);
            border: 1px solid rgba(221, 221, 221, 1);
            border-radius: 3px;
            position: absolute;
            left: 625px;
            top: 6px;
            color: #666;
          }
          .reduceButton {
            width: 30px;
            height: 30px;
            background: rgba(246, 246, 246, 1);
            border: 1px solid rgba(221, 221, 221, 1);
            border-radius: 3px;
            position: absolute;
            left: 670px;
            top: 6px;
            color: #666;
          }
          .updateImg {
            margin-top: 14px;
            display: block;
            width: 76px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            background: rgba(0, 176, 183, 1);
            border-radius: 3px;
            font-size: 14px;
            font-family: SourceHanSansCN-Regular;
            font-weight: 400;
            color: rgba(255, 255, 255, 1);
            cursor: pointer;
          }
          .modelDetail {
            display: flex;
            align-items: center;
            height: 168px;
            margin-top: 14px;
            .modelDiv {
              .everyModel {
                cursor: pointer;
                width: 300px;
                margin-right: 12px;
                height: 168px;
                // background: rgba(238, 238, 238, 1);
                border: 1px solid #eee;
                border-radius: 3px;
                position: relative;
                text-align: center;
                .modifyImg {
                  position: absolute;
                  width: 100%;
                  height: 168px;
                  line-height: 168px;
                  left: 0;
                  right: 0;
                  top: 0;
                  bottom: 0;
                  margin: auto;
                  z-index: 2;
                  background: rgba(0, 0, 0, 0.2);
                  text-align: center;
                  color: #fff;
                  cursor: pointer;
                  font-size: 14px;
                  display: none;
                }
                &:hover .modifyImg {
                  display: block;
                }
                .detailImg {
                  cursor: pointer;
                  position: absolute;
                  left: 0;
                  right: 0;
                  top: 0;
                  bottom: 0;
                  margin: auto;
                  max-width: 292px;
                  max-height: 160px;
                }
                .deleteDiv {
                  position: absolute;
                  z-index: 5;
                  right: 10px;
                  top: 10px;
                  width: 37px;
                  height: 37px;
                  background: rgba(0, 0, 0, 1);
                  opacity: 0.3;
                  border-radius: 3px;
                  .deleteImg {
                    margin: 8px;
                    width: 21px;
                    height: 20px;
                  }
                  display: none;
                  cursor: pointer;
                }
                &:hover .deleteDiv {
                  display: block;
                }
              }
            }
          }
        }
      }

 

 

 

相關文章