vue实现分片上传

需要将文件按照一定大小进行分片,一次请求只发送这一小片数据,所以我们可以同时发起多个请求。但一次同时请求的连接数不宜过多,服务器负载过重。

一、HTML部分

根据element-ui上传组件配置相关参数,详情查看官网

element-ui文档

<el-upload ref='uploadImg' drag multiple 
	:file-list="uploadimg" :show-file-list="false"
    :on-change="beforeAvatarUpload" 
    accept=" .jpg, .jpeg, .png"  
    action=process.env.VUE_APP_UPLOAD_API
    :http-request="uploadFile" :on-success="uploadSuccess">
    <i class="el-icon-plus">i>
    <div class="loadTxt already">
    	已上传({{this.uploadimg.length || 0}}/50张)
    div>
    <div class="loadTxt">拖拽图片到此处或点击上传div>
el-upload>
二、上传前钩子

上传的文件验证

 beforeAvatarUpload(file) {
		this.newUploadImg.push({id:file.uid,baseUrl:URL.createObjectURL(file.raw),status:true})
        let beforePath = URL.createObjectURL(file.raw)
        const doubleName = this.uploadimg.map(v => {
          if (v.name === file.name) {
            this.$message.error('该图片已上传,请勿重复发布')
            this.doubleName = false
            return false
          }
          console.log(this.uploadimg)
          if(v.file&&(v.file.uid === file.uid)){
            v.beforePath = beforePath
          }
        })

        var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
        const extension =
          testmsg === "jpg" ||
          testmsg === "JPG" ||
          testmsg === "png" ||
          testmsg === "PNG" ||
          testmsg === "bpm" ||
          testmsg === "JPEG" ||
          testmsg === "jpeg" ||
          testmsg === "TIF" ||
          testmsg === "TIFF" ||
          testmsg === "BPM";
        const isLt50M = file.size / 1024 / 1024 < 50;
        if (!extension) {
          this.$message({
            message: "发布图片只能是JPG,PNG,JPEG,BMP,TIF,TIFF格式!",
            type: "error"
          });
          return false; //必须加上return false; 才能阻止
        }
        if (!isLt50M) {
          this.$message({
            message: "发布文件大小不能超过 50MB!",
            type: "error"
          });
          return false;
        }
        return extension && isLt50M && doubleName;
      },
三、上传图片

使用前端直接上传文件到阿里云OSS

oss前端实例

	// 上传图片
     async uploadFile(option) {
        this.explainShow = false
        this.imgsNumer = this.imgsNumer + 1
        if (this.imgsNumer < 51) {//判断上传图片限制

          var testmsg = option.file.name.substring(option.file.name.lastIndexOf(".") + 1);
          const extension = //判断图片类型
            testmsg === "jpg" ||
            testmsg === "JPG" ||
            testmsg === "png" ||
            testmsg === "PNG" ||
            testmsg === "bpm" ||
            testmsg === "JPEG" ||
            testmsg === "jpeg" ||
            testmsg === "TIF" ||
            testmsg === "TIFF" ||
            testmsg === "BPM";

          if (extension && this.doubleName) {
            try {
              if (option.file.uid !== null && option.file.uid !== undefined) {
                //构建上传文件参数
                this.fileLoading = true;
                //获取上传文件所需要的STS Token
                let imgInfo = {
                  ...option
                }
                this.uploadimg.push(imgInfo)
                let formData = new FormData()
                formData.append('file', option.file)
                let client = new OSS({
                  region: "oss-cn-shanghai",
                  accessKeyId: this.accessKeyId,
                  accessKeySecret: this.accessKeySecret,
                  stsToken: this.securityToken,
                  bucket: process.env.VUE_APP_BUCKET,
                  secure: true,
                });
                let objectName = "gallery/" + option.file.uid + option.file.name;
                let fileName = option.file.name;
                // 分片上传文件
                let that = this;
                let result = await client.multipartUpload(objectName, option.file, {
                  //进度条更新
                  progress: async function(p) {
                    let progressPercent = parseInt(p * 100);
                    that.uploadimg.forEach(item => {
                      if (item.file) {
                        that.newUploadImg.forEach(itm => {
                          if(item.file.uid === itm.id){
                            item.baseUrl = itm.baseUrl
                          }
                        })
                        if (item.file.uid === option.file.uid) {
                          item.progressPercent = progressPercent
                          item.uploadSuccess = false
                          // item.beforePath = option
                          // that.isDisabled = true
                          item.uploadSelect = true
                          if (progressPercent === 100) {
                            item.progressPercent = 99
                          }
                          that.$forceUpdate()
                        }
                      }
                    })
                  },
                  timeout: 6000000,
                  partSize: 1024 * 1000 * 0.5,
                  callback: {
                    url: process.env.VUE_APP_CALLBACK_URL,
                    host: "oss-cn-shanghai.aliyuncs.com",
                    body: "object=${object}&bucket=${bucket}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&var1=${x:myname}",
                    contentType: "application/json",
                    customValue: {
                      "x:myname": fileName
                    },
                  },
                });
                if (result.res.statusCode === 200) {
                  // this.$message.success("上传成功");
                  this.opcityForm = 1
                  this.cityDisabled = false
                  this.uploading = false
                  imgInfo = {
                    ...imgInfo,
                    height: result.data.height,
                    lengthType: result.data.lengthType,
                    path: result.data.path,
                    size: result.data.size,
                    width: result.data.height,
                    type: result.data.type,
                    fileName: result.name,
                    name: result.name,
                    action: false,
                    dataFlag: false, //图片信息是否填写
                    isCover: '0', //是否是封面
                    progressPercent: 100,
                    uploadSelect: false,
                  };

                  if (this.loadType == '1') {
                    imgInfo.groupId = this.ImgGroup[0].groupId;
                    imgInfo.bgColor = this.ImgGroup[0].color;
                  }

                  this.uploadimg.forEach((itm, index) => {
                    if (itm.file) {
                      if (itm.file.uid === option.file.uid) {
                        this.uploadimg.splice(index, 1)
                      }
                    }
                  })
                  
                  this.uploadimg.push(imgInfo)
                } else {
                  this.$message.error("上传失败");
                }
              }
            } catch (error) {
              console.log(error)
              this.$message.error("网络中断请重新上传");
            }
          }
        } else {
          if (this.imgsNumer == 51) {
            this.$message.error("上传数量已达上限")
            setTimeout(() => {
              this.imgsNumer = 50;
            }, 1000)
          }
        }
      },

你可能感兴趣的:(vue,分片上传,javascript,vue.js,html5)