1. 程式人生 > 其它 >element 實現檔案上傳:只能上傳一個,且能覆蓋上傳 & 檔案大小,型別限制

element 實現檔案上傳:只能上傳一個,且能覆蓋上傳 & 檔案大小,型別限制

技術標籤:jsvue

需求:
在檔案滿足條件時直接上傳,再次上傳時若檔案滿足條件則覆蓋之前的檔案上傳,否則則提示且不上傳不滿足條件的檔案。

<!-- :limit="1" --> // 注意:最大允許上傳個數:這裡不要置為1,置為1有個問題就是:無論怎麼選擇檔案,頁面上展示的始終是第一次選擇的檔案,這效果和我想的大相徑庭。
<el-upload
   ref="upload"
   class="uploadBox"
   :action="$config.baseURL + '/resource/upload/images'"
   :http-request="handleFileUpload"
   :on-change="handleChange" 
   :auto-upload="false"   // 注意1
   :before-upload="beforeFileUpload"  // 注意2:
   :file-list="fileList"   //  上傳的檔案列表
   :show-file-list="isShowList"  // 是否顯示已上傳檔案列表
   :on-remove="handleFileRemove"
 >
   <el-button type="primary" size="small" >上傳檔案</el-button>
   <div slot="tip" class="el-upload__tip">注:僅支援zip格式壓縮檔案</div>
 </el-upload>

:auto-upload:// 是否在選取檔案後立即進行上傳
:on-change:// 檔案狀態改變時的鉤子,新增檔案、上傳成功和上傳失敗時都會被呼叫
:before-upload: // 上傳檔案之前的鉤子,引數為上傳的檔案,若返回 false 或者返回 Promise 且被 reject,則停止上傳。
:http-request: // 覆蓋預設的上傳行為,可以自定義上傳的實現
:on-remove: // 檔案列表移除檔案時的鉤子

data() {
	return {
		isShowList:false,
		fileList:[ ]
	}
}

methods方法

// 點選上傳檔案的按鈕:
  handleChange(file, fileList) {
	 // 限制大小在10MB之內
      let isLt10M = file.size / 1024 / 1024 < 10
      if(!isLt10M) {
        this.$message.error("上傳檔案大小不能超過 10MB!")
      }
      // 限制類型只能為zip
      let isResPackage = file.raw.type.includes('zip') // 是否為zip格式
      if(!isResPackage){
        this.$message.error("請上傳正確格式的檔案!")
      }
      // 只有兩個條件都滿足的時候,根據檔案數量判斷
      if(isResPackage && isLt10M) {
       // 若檔案>1個,則取第二個檔案上傳
        if(fileList.length > 1) {
          this.fileList = [fileList[fileList.length - 1]]
          this.$nextTick(()=>{
           // 主動去呼叫提交介面
            this.$refs.upload.submit();
          })
          // 若檔案只有一個,直接上傳
        } else {
          this.$refs.upload.submit();
        }
        // 若任意不滿足一個條件,則不進行上傳動作,根據數量判斷
      } else {
       // 若檔案>1,則保留第一個上傳的檔案
        if(fileList.length > 1) {
          this.fileList = [fileList[0]]
          // 當只有當前這一個檔案時,則清空檔案列表
        } else {
          this.fileList = []
          // this.$refs.upload.clearFiles() // 清除前端顯示的檔案列表
        }
      }
    },
  //檔案上傳條件 
  beforeFileUpload(file) {
    console.log(file,'file的資訊')
    //注意:當有如題的需求時,可把這裡的限制邏輯移至:on-change鉤子中
    // let isResPackage = file.type.includes('zip') // 是否為zip格式
    // let isLt10M = file.size / 1024 / 1024 < 10
    // if(!isResPackage){
    //   this.$message.error("請上傳正確格式的檔案!")
    // }
    // if(!isLt10M) {
    //   this.$message.error("上傳檔案大小不能超過 10MB!")
    // }
    // return isResPackage && isLt10M;
  },
  // 自定義檔案上傳
    handleFileUpload(e) {
      console.log(e.file);
      this.isShowList = true;
      const that = this;
      this.ossUpload(e.file, {
        progress: (p, checkpoint) => {
          //因為是el-upload元件自定義上傳,若需要顯示進度條,必須手動呼叫進度條方法
          that.progress = p;
          e.onProgress({ percent: Math.floor(p * 100) }); // 觸發el-upload元件的onProgress方法
        }
      })
        .then(result => {
          console.log(result);
          let index = result.res.requestUrls[0].indexOf("?");
          if (index != -1)
            that.advSubmitData.extFile = result.res.requestUrls[0].substring(0, index);
          else that.advSubmitData.extFile = result.res.requestUrls[0];
          that.$message.success("檔案上傳成功");
        })
        .catch(e => {
          that.$message.error("檔案上傳失敗");
        });
    },
    //移除上傳檔案
    handleFileRemove(file, fileList) {
      console.log(file,fileList);
      this.advSubmitData.extFile = "";
    },  

頁面顯示上面:使用者選擇第二個檔案後,從第一個檔案到第二個檔案,有很明顯的動態切換的效果,如果不想要,可以通過下面的css程式碼去覆蓋:

<style lang="scss" scoped>
    .upload-demo {
      display: flex;
    }
    /deep/ .el-list-enter-active,
    /deep/ .el-list-leave-active {
      transition: none;
    }
 
    /deep/ .el-list-enter,
    /deep/ .el-list-leave-active {
      opacity: 0;
    }
    /deep/ .el-upload-list {
      height: 40px;
    }
</style>

注意,VUE3.0下/deep/的使用可能會有報錯,比如我的專案就報錯了:
這時可以把/deep/替換為::v-deep

關於/deep/和>>>和::v-deep