elementui 上传文件&上传图片

2,055 阅读1分钟

七牛云上传文件

注意abort()

  • 上传过程中取消上传abort()
this.$refs.upload.abort()

上传组件

<el-upload
  class="upload-demo"
  action="https://up.qbox.me"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :on-success="successCallback"
  :before-remove="beforeRemove"
  multiple
  :before-upload='beforeUpload'
  :data="formList"
  :limit="5"
  :on-exceed="handleExceed"
  accept=".doc,.docx,.xls,.xlsx,.txt,.pdf,.jpg,.png"
  :file-list="formData.cdtPurchaseOrderRecordModel.filePathArray">
  <span style="margin-right:15px;">附件:</span>
  <el-button size="small" type="primary">点击上传</el-button>
  <span slot="tip" class="el-upload__tip" style="margin-left:15px;">(兼容5个以内的附件,每个大小不超过100M,支持word/excel/pdf/txt/jpg/png)</span>
</el-upload>
  • :data="formList" data是上传附带的额外参数

上传过程中的周期方法

/**
 * 上传文件之前配置参数  新增采购单附件上传文件限制再100M
 * @author cy
 * @date 2019-12-04 16:48
 * @param {上传的文件}
 * @returns
 */
beforeUpload (file) {
  const isLt2M = file.size / 1024 / 1024 < 100
  if (!isLt2M) {
    this.$message({
      message: '上传文件大小不能超过 100MB!',
      type: 'warning'
    })
    return
  }

  let FileExt = file.name.replace(/.+\./, '')
  if (['doc', 'docx', 'xls', 'xlsx', 'pdf', 'txt', 'jpg', 'png'].indexOf(FileExt.toLowerCase()) === -1) {
    this.$message({ type: 'warning', message: '请上传后缀名为[.doc,.docx,.xls,.xlsx,.txt,.pdf,.jpg,.png]的附件!' })
    return
  }
  // 上传开始
  this.isUploading = true
  let suffixName = file.name.split('.')[1]
  this.formList.key = hexMd5(Math.random() + new Date()) + '.' + suffixName
  this.formList.token =
        '' // uptoken 是上传凭证,由其他程序生成
},
/**
 * 文件超过限制时的钩子
 * @author cy
 * @date 2019-12-04 16:48
 * @param {files: 本次上传的文件, fileList: 已经上传的文件}
 * @returns
 */
handleExceed (files, fileList) {
  this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
/**
 * 点击文件列表事件
 * @author cy
 * @date 2019-12-04 16:50
 * @param {file: 上传的文件}
 * @returns
 */
handlePreview (file) {
  if (file.filePath === undefined) {
    return false
  }
  let url = encodeURI(this.$Base64.decode(file.filePath.substring(4, file.filePath.length - 9)), 'utf-8')
  // 添加文件名称 七牛云的写法
  location.href = url + '?attname=' + file.name
},
  • file.filePath是一串字符串 需要解码

解码方式

  • 1.安装js-base64
import { Base64 } from 'js-base64'
Vue.prototype.$base64 = Base64
  • this.$Base64.decode 解码 将其他编码的字符串转化成utf-8的编码
  • 或者不安装js-base64 使用window自带的方法atob解码 btoa编码

上传图片

  • 上传前的验证,大小,是否要压缩等
    // 上传前参数准备
    async beforeUpload (file) {
      let files = file
      // 图片比例校验
      if (file.size / (1024 * 1024) > 3) {
        showLoading({ text: '图片太大,上传时间可能过长,上传中...' })
      } else {
        showLoading({ text: '上传中...' })
      }
      if (this.uploadOption.scale || this.uploadOption.isLimitWH) {
        let reader = new FileReader()
        reader.onload = (e) => {
          let data = e.target.result
          let img = new Image()
          img.src = data
          img.onload = () => {
            if (this.uploadOption.scale) {
              if (img.width / img.height !== this.uploadOption.scale) {
                this.$message.error(`请上传比例为${this.uploadOption.scale}图片,建议尺寸${this.uploadOption.suggest}`)
                this.$refs.upload.abort()
              }
            }
            if (this.uploadOption.isLimitWH) {
              if (img.width > this.uploadOption.limitWidth || img.height > this.uploadOption.limitHeight) {
                this.$message.error(`上传图片尺寸不对,必须上传尺寸为${this.uploadOption.limitWidth}*${this.uploadOption.limitHeight}的图片`)
                this.$refs.upload.abort()
              }
            }
            hideLoading()
          }
        }
        reader.readAsDataURL(file)
      }
      if (this.uploadOption.isCompress) {
        await this.compress(file).then((res) => { // 压缩
          files = res
        })
      }
      this.formList.key = hexMd5(Math.random() + new Date())
      this.formList.token =
        '' // uptoken 是上传凭证,由其他程序生成
      return Promise.resolve(files)
    },
    // 压缩函数
    compress (file) {
      let reader = new FileReader()
      return new Promise((resolve, reject) => {
        reader.onload = (e) => {
          let data = e.target.result
          let img = new Image()
          img.src = data
          img.onload = () => { // canvas画图
            var canvas = document.createElement('canvas')
            var context = canvas.getContext('2d')
            let canvasWidth = img.width * (this.uploadOption.compressScale ? this.uploadOption.compressScale : 1)
            let canvasHeight = img.height * (this.uploadOption.compressScale ? this.uploadOption.compressScale : 1)
            let qualityArgument = this.uploadOption.qualityArgument ? this.uploadOption.qualityArgument : 1
            canvas.width = canvasWidth
            canvas.height = canvasHeight
            context.clearRect(0, 0, canvasWidth, canvasHeight)
            context.drawImage(img, 0, 0, canvasWidth, canvasHeight)
            resolve(this.base64ToFile(canvas.toDataURL(file.type, qualityArgument), file.name))
          }
        }
        reader.readAsDataURL(file)
      })
    },
    // base64转file
    base64ToFile (dataurl, filename) {
      let arr = dataurl.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    },