vue+elementui运用el-upload结合cos-js-sdk-v5实现腾讯云cos文件上传

npm install cos-js-sdk-v5

下面展示 upload.js

// An highlighted block
import COS from 'cos-js-sdk-v5'
import { getSecret } from '@/api/upload'

export default function upload(file, config, callback) {
  if (typeof config.isPublic === 'undefined') {
    config.isPublic = true
  }
  getSecret({
    type: config.type,
    path: config.path,
    isPublic: config.isPublic ? config.isPublic : false
  }).then(response => {
    const data = response.data
    const cos = new COS({
      getAuthorization: function(options, callback) {
        callback({
          TmpSecretId: data.tmpSecretId,
          TmpSecretKey: data.tmpSecretKey,
          XCosSecurityToken: data.sessionToken,
          ExpiredTime: data.expiredTime
        })
      }
    })

    return {
      cos: cos,
      dir: data.url,
      bucket: data.bucket,
      region: data.region
    }
  }).then(data => {
    const cos = data.cos
    const dir = data.dir
    const bucket = data.bucket
    const region = data.region

    const url = cos.getObjectUrl({
      Bucket: bucket,
      Region: region,
      Key: `${dir}/${file.name}`,
      Sign: false
    }, function(data) {
      cos.putObject({
        Bucket: bucket,
        Region: region,
        Key: `${dir}/${file.name}`,
        Body: file
      }, function(data) {
        if (config.isPublic) {
          callback(url.replace(/^http(s)?:\/\/(.*?)\//, 'https://www.baidu.com/'))
        } else {
          callback(url)
        }
      })
    })
  })
}

子组件调用例子

下面展示一些 子组件调用代码

// An highlighted block
<template>
  <div class="merchant-create-modify-page">
    <el-form ref="form" :model="formData" :rules="rules" label-width="150px" style="width: 100%">
      <el-form-item label="营业执照扫描件">
        <el-upload
          ref="upload"
          action="#999"
          list-type="picture-card"
          accept="image/jpeg,image/png,image/jpg"
          :file-list="licenseImageUrl"
          :limit="1"
          :auto-upload="false"
          :style="{width: '900px'}"
          :on-preview="handlePictureCardPreview"
          :on-change="singleFileChange"
          :on-exceed="singleExceed"
          :on-remove="singleRemove"
        >
          <el-button :disabled="licenseImageUrl.length >= 1" size="small" type="primary">上传图片</el-button>
        </el-upload>
        <span class="tip">提示:图片格式为JPGJPEGPNG,大小不超过5M</span>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
      </el-form-item>
      <el-form-item label="其他证件扫描件">
        <el-upload
          action="#999"
          list-type="picture-card"
          accept="image/jpeg,image/png,image/jpg"
          :file-list="formData.mchCertificates"
          :limit="5"
          :auto-upload="false"
          :style="{width: '900px'}"
          :on-preview="handlePictureCardPreview"
          :on-change="multipleFileChange"
          :on-exceed="multipleExceed"
          :before-remove="multipleRemove"
        >
          <el-button :disabled="formData.mchCertificates.length >= 5" size="small" type="primary">上传图片</el-button>
        </el-upload>
        <span class="tip">提示:图片格式为JPGJPEGPNG,大小不超过5M,最多上传5</span>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
      </el-form-item>

      <el-form-item>
        <el-button @click="goBack">取消</el-button>
        <el-button type="primary" @click="onSubmit">保存</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import Title from './components/Title'
import moment from 'moment'
import SortFile from './components/SortFile'
import { merchantSave, merchantUpdate, merchantInfo, uploadDocumentConfig, uploadLogoConfig, getSign } from '@/api/merchant'
import upload from '@/utils/upload'

const defaultFormData = {
  mchType: '1',
  sendWay: ['1'],
  taxType: '',
  receiptKind: '1',
  receiptType: '1',
  billingCycle: '1',
  mchProperty: '2',
  companyName: '',
  companyTax: '',
  companyAddress: '',
  companyTel: '',
  companyBank: '',
  companyBankNo: '',
  registerTime: null,
  validationBegin: null,
  validationEnd: null
}

export default {
  components: { Title, SortFile },
  data() {
    return {
      pageType: 'create',
      dialogImageUrl: '',
      dialogVisible: false,
      sendWayDisable1: false,
      sendWayDisable2: false,
      sendWay: [],
      logoUrl: [],
      licenseImageUrl: [],
      uploadDocumentConfig: uploadDocumentConfig,
      uploadLogoConfig: uploadLogoConfig,
      formData: { ...defaultFormData, mchCertificates: [] },
      requestStatus: {}
    }
  },

  methods: {
    // 图片上传
    async singleFileChange(file, fileList) {
      const isOverSize = 5 * 1024 * 1024
      const fileTypeArray = ['image/jpeg', 'image/png', 'image/jpg']
      if (file.size > isOverSize) {
        this.formData = { ...this.formData }
        fileList.pop()
        return this.$message({ message: '图片大小不超过5M', type: 'warning' })
      }
      if (!fileTypeArray.find(type => type === file.raw.type)) {
        this.formData = { ...this.formData }
        fileList.pop()
        return this.$message({ message: '格式为JPG、JPEG、PNG', type: 'warning' })
      }
      const currentTime = moment(Date.now()).format('YYYYMMDDHHmmss')
      const name = file.name.split('.')[0]
      const type = file.name.split('.')[1]
      const copyFile = new File([file.raw], `${name}_${currentTime}.${type}`)
      upload(copyFile, this.uploadDocumentConfig, url => {
        if (url) {
          const params = {
            path: url
          }
          getSign(params).then(res => {
            this.licenseImageUrl.push({
              ...file,
              percentage: 100,
              status: 'success',
              url: url + '?' + res.data,
              logo: url
            })
          })
        }
      })
    },
    async multipleFileChange(file, fileList) {
      const isOverSize = 5 * 1024 * 1024
      const fileTypeArray = ['image/jpeg', 'image/png', 'image/jpg']
      if (file.size > isOverSize) {
        this.formData = { ...this.formData }
        fileList.pop()
        return this.$message({ message: '图片大小不超过5M', type: 'warning' })
      }
      if (!fileTypeArray.find(type => type === file.raw.type)) {
        this.formData = { ...this.formData }
        fileList.pop()
        return this.$message({ message: '格式为JPG、JPEG、PNG', type: 'warning' })
      }
      const currentTime = moment(Date.now()).format('YYYYMMDDHHmmss')
      const name = file.name.split('.')[0]
      const type = file.name.split('.')[1]
      const copyFile = new File([file.raw], `${name}_${currentTime}.${type}`)
      upload(copyFile, this.uploadDocumentConfig, url => {
        if (url) {
          const formData = this.formData
          const params = {
            path: url
          }
          getSign(params).then(res => {
            formData.mchCertificates.push({
              ...file,
              percentage: 100,
              status: 'success',
              url: url + '?' + res.data,
              logo: url
            })
            this.formData = { ...formData }
          })
        }
      })
    },
    singleRemove(file, licenseImageUrl) {
      this.licenseImageUrl = []
      this.formData.licenseImageUrl = ''
      this.$refs.upload.clearFiles()
    },
    multipleRemove(file) {
      const formData = this.formData
      const deleteIndex = formData.mchCertificates.findIndex(img => file.url === img.url)
      formData.mchCertificates.splice(deleteIndex, 1)
      this.formData = { ...formData }
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    singleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 1 张图片`)
    },
    multipleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 5 张图片`)
    },

    goBack() {
      this.$router.back()
    },
  }
}
</script>

你可能感兴趣的:(vue)