vue图片上传(支持单个、批量)

时间:2021-07-13
本文章向大家介绍vue图片上传(支持单个、批量),主要包括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) } }) } }

原文地址:https://www.cnblogs.com/shyhuahua/p/15005635.html