ant design of vue 之文件上传组件(腾讯云)封装

原理:通过调用后台接口获取腾讯云秘钥,然后将秘钥以及文件信息上传到腾讯云,获取文件腾讯云存储信息,最后组件将腾讯云存储信息返回出去,在组件外部调用后台接口将腾讯云信息存到后台。

安装cos-js-sdk-v5依赖

npm i cos-js-sdk-v5 --save

参考cos-js-sdk-v5

uuid.js文件

在src的utils文件夹中新增uuid.js文件

/* eslint-disable */
export default (len, radix) => {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');

  var uuid = [],
    i;
  radix = radix || chars.length;
  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
  } else {
    // rfc4122, version 4 form
    var r;

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';
    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random() * 16;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  return uuid.join('');
}

system.config.js文件

在src的config文件夹中新增system.config.js文件

/**
 * 系统配置文件
 */
/* eslint-disable */
// 系统配置 ,在模块中使用方法: this.$CONFIG.xxxx 
const config = {
  //系统名称
  systemTitle:'安全生产标准化管理体系网',
  //系统描述
  systemDescription:'业界领先的信息聚合平台',
  //系统底部 copyright@公司名称
  footerComName:'信息科技有限公司',
  //腾讯云存储
  Bucket: 'test-1256342487',
  Region: 'ap-chengdu',
  //后台接口地址
  serverUrl:'http://123.206.76.136/news/api'
  
}
export default config

在main.js文件中进行全局属性配置

import config from '@/config/system.config'
// 引入全局自定义配置文件
Vue.CONFIG = Vue.prototype.$CONFIG = config

封装组件

/* eslint-disable space-before-function-paren */ 
/* eslint-disable space-before-function-paren */ 
//eslint-disable-next-line vue/valid-template-root
<template>
  <div class="clearfix">
    <a-upload name="file"
              :multiple="true"
              :showUploadList="true"
              :remove="remove"
              :fileList="fileList"
              :beforeUpload="beforeUpload"
              :customRequest="customRequest"
              :accept="accept.join(',')"
              class="upload-list-inline"
              listType="picture">
      <a-button v-if="fileList.length < maxLength">
        <a-icon type="upload" />上传
      </a-button>
    </a-upload>
  </div>
</template>
import COS from 'cos-js-sdk-v5'
import { getCredential } from '@/api/upload'
import uuid from '@/utils/uuid'
export default {
  name: 'UploadFile',
  props: {
    /**
   * 格式示例:
   * [{
        uid: '-1',
        name: 'xxx.png',
        status: 'done',
        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
      }]
             */
    files: {
      type: Array,
      required: false,
      default: () => []
    },
    maxLength: {
      type: Number,
      required: false,
      default: () => 1000
    },
    maxSize: {
      type: Number,
      required: false,
      default: () => 102400
    },
    editable: {
      type: Boolean,
      required: false,
      default: () => true
    },
    accept: {
      type: Array,
      required: false,
      default: () => []
    }
  },
  data () {
    return {
      cos: null,
      fileList: []
    }
  },
  watch: {
    files (list) {
      this.fileList = list
    }
  },
  created () {
    // 初始化腾讯云上传
    this.cos = new COS({
      getAuthorization: (options, callback) => {
        getCredential().then(data => {
          callback({
            TmpSecretId: data.tmpSecretId,
            TmpSecretKey: data.tmpSecretKey,
            XCosSecurityToken: data.sessionToken,
            ExpiredTime: data.expiredTime
          })
        })
      }
    })
  },
  methods: {
    // 上传之前判断文件大小   即使选择多个文件,beforeUpload也会调用多次
    beforeUpload (file) {
      // 文件小于100M才能上传
      const isSize = Number((file.size / 1024).toFixed(2)) > this.maxSize
      if (isSize) {
        this.$message.error('请上传文件小于100M')
        return false
      } else {
        return true
      }
    },
    customRequest (info) {
      const { file } = info
      // debugger
      const that = this
      const uid = uuid(32)
      const extName = that.getExtName(file.name)
      // const fileName = `${uid}.${extName}`
      const fileName = that.getFileName(file.name) + '' + (new Date()).getTime() + '.' + extName
      const size = Number((file.size / 1024).toFixed(2))
      const { accept } = that
      if (accept.length && !accept.includes(`.${extName}`.toLowerCase())) {
        that.$message.error('文件格式错误')
        return
      }
      this.cos.putObject(
        {
          Bucket: that.$CONFIG.Bucket,
          Region: that.$CONFIG.Region,
          Key: fileName,
          Body: file, // 上传文件对象
          onProgress: progressData => {
            // that.progress = progressData.percent
          }
        },
        function (err, data) {
          if (err) {
            that.$notification.error({
              message: '文件上传错误',
              description: err.Message
            })
          } else {
            const url = `http://${data['Location']}`
            that.fileList.push({
              uid,
              size,
              name: file.name,
              type: file.type,
              status: 'done',
              url,
              rename: fileName,
              extName,
              thumbnailUrl: url
            })
            that.$emit('change', that.fileList)
          }
        }
      )
    },
    remove (file) {
      const that = this
      this.fileList = this.fileList.filter(item => item.uid !== file.uid)
      that.$emit('change', that.fileList)
    },
    getExtName (fileName) {
      const index = fileName.lastIndexOf('.')
      if (index > -1) {
        return fileName.substring(index + 1)
      } else {
        return ''
      }
    },
    getFileName (fileName) {
      const index = fileName.lastIndexOf('.')
      if (index > -1) {
        return fileName.slice(0, index)
      } else {
        return ''
      }
    }
  }
}
</script>
<style scoped>
/* tile uploaded pictures */
.upload-list-inline >>> .ant-upload-list-item {
  float: left;
  width: 200px;
  margin-right: 8px;
}
.upload-list-inline >>> .ant-upload-animate-enter {
  animation-name: uploadAnimateInlineIn;
}
.upload-list-inline >>> .ant-upload-animate-leave {
  animation-name: uploadAnimateInlineOut;
}
</style>

使用

<upload-file 
	:accept="['.doc','.docx','.ppt','.pptx','.pdf','.pdfx','.xls','.xlsx']"
	:files="fileList" 
	@change="uploadFile"></upload-file>
// 上传附件返回数据
    uploadFile(files){
     console.log("uploadFile",files)
     this.articleAttachmentList = files.map(item=>({
       attachmentExtensionName:item.extName,//文件扩展名
       attachmentLogicalFilename:item.name,//文件显示名
       attachmentPhysicalFilename:item.rename,//文件存储名
       attachmentSize:item.size,//文件大小
       attachmentUrl:item.url,//文件路径
     }))
   },

// 获取数据给组件显示
this.fileList = articleAttachmentList.map((item,index)=>({
   uid:index,
   name: item.attachmentLogicalFilename,
   status:"done",
   url: item.attachmentUrl,
   reName: item.attachmentPhysicalFilename,
   extName: item.attachmentExtensionName,
   size:0,
   thumbnailUrl:""
 }))
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值