el-upload 的改写

501 阅读1分钟

1.官方写法如下

<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :before-remove="beforeRemove"
  multiple
  :limit="3"
  :on-exceed="handleExceed"
  :file-list="fileList">
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

2.改造- 通过改造http-request赋值的方法,取到file对象,同时自定义自己的参数。

<el-upload
   class="upload-demo"
   action="#"
   accept=".jpg, .jpeg, .png"
   :auto-upload="true"
   :http-request="(file)=>{uploadIcon(file,`${index}`)}"
   :show-file-list="false"
   :before-upload="beforeIconUpload"
 >
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">支持扩展名:.png .jpg</div>
</el-upload>

upload(file,index){
    //...上传操作
}

3.对上传的图片进行压缩处理

 // 自定义上传
    handleUpload(res, theItem) {
      theItem.isLoading = true
      this.compress(res.file, async(newFile) => {
        const formData = new FormData()
        formData.append("files", newFile)
        formData.append("businessTypeId", 1)
        formData.append("businessId", this.staffId)
        try {
          const res = await batchUpload(formData)
          const data = res.data
          theItem.fileList = data.map(item => {
            item.url = item.absUrl
            return item
          })
        } catch {
          this.$refs[theItem.typeKey].clearFiles()
        }
        setTimeout(() => {
          theItem.isLoading = false
        }, 600)
      })
    },
    
    
      // 图片压缩
    compress(fileObj, callback) {
      try {
        const image = new Image()
        image.src = URL.createObjectURL(fileObj)
        image.onload = () => {
          // 默认按比例压缩
          let w = image.width
          let h = image.height
          const scale = w / h
          w = fileObj.width || w
          h = fileObj.height || (w / scale)
          let quality = 0.4 // 默认图片质量为0.4
          // 生成canvas
          const canvas = document.createElement("canvas")
          const ctx = canvas.getContext("2d")
          // 创建属性节点
          const anw = document.createAttribute("width")
          anw.nodeValue = w
          const anh = document.createAttribute("height")
          anh.nodeValue = h
          canvas.setAttributeNode(anw)
          canvas.setAttributeNode(anh)
          console.log(w, h, "w, hw, h")
          ctx.drawImage(image, 0, 0, w, h)
          // 图像质量
          if (fileObj.quality && fileObj.quality <= 1 && fileObj.quality > 0) {
            quality = fileObj.quality
          }
          // quality值越小,所绘制出的图像越模糊
          const data = canvas.toDataURL("image/jpeg", quality)
          // 压缩完成执行回调
          const newFile = this.convertBase64UrlToBlob(data, fileObj.name)
          callback(newFile)
        }
      } catch (e) {
        console.log("压缩失败!")
      }
    },
    //url 转blob
    convertBase64UrlToBlob(urlData, filename) {
      const bytes = window.atob(urlData.split(",")[1]) // 去掉url的头,并转换为byte
      // 处理异常,将ascii码小于0的转换为大于0
      const ab = new ArrayBuffer(bytes.length)
      const ia = new Uint8Array(ab)
      for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i)
      }
      return new File([ab], filename, { type: "image/png" })
    }