vue圖片上傳(支持單個、批量)


項目中一個小需求,描述一下:

意見反饋模板,可以上傳3張圖片,每上傳1張圖片,增加1個占位圖,最多上傳3張。上傳到第三張圖片占位圖消失。且支持單個、批量上傳。支持顯示上傳進度。如圖顯示:

elementUI組件里的,只支持一個個圖片上傳,這里不采用。

下面說下解決方案:使用input  type='file'

第一步:組件里:

// this.imageList圖片超過3張就隱藏上傳按鈕
<div v-if="this.imageList.length !== 3">
    <i class="el-icon-plus"></i>
    <input
     type="file"
     title=""
     :multiple="true"
     ref="myfile"
     class="select-file-input"
     accept=".jpg,.jpeg,.png"
     @change="handleFileChange"
   />
</div>

第二步:methods里面:

handleFileChange(e) {
      this.files = Array.prototype.slice.call(e.target.files)
      //  圖片數量校驗
      if (this.files.length > 3) {
        this._message.warning('最多選擇3張圖片')
        this.files = []
        return false
      } else if (this.imageList.length === 1 && this.files.length > 2) {
        this._message.warning('最多選擇2張圖片')
        return false
      } else if (this.imageList.length === 2 && this.files.length > 1) {
        this._message.warning('最多選擇1張圖片')
        return false
      } else {
     // 圖片格式的校驗
        this.imgType = this.files.some(v => {
          let index = v.name.lastIndexOf('.')
          return (
            v.name.substring(index + 1, v.name.length) !== 'png' &&
            v.name.substring(index + 1, v.name.length) !== 'jpg' &&
            v.name.substring(index + 1, v.name.length) !== 'jpeg' &&
            v.name.substring(index + 1, v.name.length) !== 'PNG' &&
            v.name.substring(index + 1, v.name.length) !== 'JPG' &&
            v.name.substring(index + 1, v.name.length) !== 'JPEG'
          )
        })
        if (this.imgType) {
          this._message.warning('上傳圖片只能是 png、jpeg、jpg格式!')
          this.$refs.myfile.value = null;
          return false
        }
        // 判斷是否超過2M
        this.sizeIsSatisfy = this.files.some(v => {
          return v.size > 2 * 1024 * 1024
        })
        if (this.sizeIsSatisfy) {
          this._message.warning('單張圖片超過2M')
          this.$refs.myfile.value = null;
          return false
        } else {
          this.send()
          this.$refs.myfile.value = null;  // 清空value值,否則選擇2張相同圖片無法觸發change
        }
      }
    }

    // 圖片上傳給后台
    send() {
      // 循環調用接口 每次傳一張圖
      for (let i = 0; i < this.files.length; i++) {
        var fileName = new FormData() // FormData 對象
        fileName.append('fileName', this.files[i])
        uploadImg(fileName).then(res => {
          if (res.status === 0) {
            this.imageList.push({
              url: this.iconUrl(res.data), // 展示的url
              dataUrl: res.data, // 傳給后台的圖片url
              videoUploadPercent: 0, // 上傳百分比
              interval: '' // 計時器
            })
          } else {
            // 上傳失敗
            this.imageList.push({
              status: 1
            })
          }
        })
      }
    },
    // 刪除圖片
    handleRemove(index) {
      for (let i = 0; i < this.imageList.length; i++) {
        this.imageList.splice(index, 1)
        return
      }
    }            

第三步:自定義上傳進度條:在watch里面監聽百分比:如果百分比為0,使用定時器每10ms增加1,當百分比為100時,清除定時器。達到一個進度條的效果。

      <div
            v-for="(item, index) in imageList"
            :key="index"
            class="img-items"
          >
            <div class="imgdiv">
              <img
                v-show="item.videoUploadPercent === 100 && !item.status"
                :src="item.url"
                alt=""
                class="imgbo"
              />
              <div
                class="percent"
                v-show="item.videoUploadPercent !== 100 && !item.status"
              >
                <div class="per-num">{{ item.videoUploadPercent }}%</div>
                <div class="per-dec">
                  正在上傳...
                </div>
              </div>
              <div class="upload-error" v-show="item.status">
                <img
                  class="error-icon"
                  src="@/assets/svg/shibai_icon.svg"
                  alt=""
                />
                <div class="upload-error-dec">上傳失敗</div>
              </div>
              <i
                v-show="item.url || item.status"
                class="icon-delete"
                @click="handleRemove(index)"
              ></i>
            </div>
          </div>
             <div class="plusdiv" v-if="this.imageList.length !== 3">
            <i class="el-icon-plus"></i>
            <input
              type="file"
              title=""
              :multiple="true"
              ref="myfile"
              class="select-file-input"
              accept=".jpg,.jpeg,.png"
              @change="handleFileChange"
            />
          </div>
  watch: {
    imageList: 'percent'
  },
methods:{
    // 圖片上傳進度條
    percent() {
      this.imageList.forEach(v => {
        if (v.videoUploadPercent === 0) {
       // 使用定時器 增加百分比 v.interval
= setInterval(() => { if (v.videoUploadPercent >= 100) { v.videoUploadPercent = 100 clearInterval(v.interval) return } v.videoUploadPercent += 1 }, 10) } else if (v.videoUploadPercent === 100) { clearInterval(v.interval) } }) } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM