vue 图片上传到腾讯云对象存储组件封装(完善版)

本文介绍了如何将Vue组件封装以实现图片上传到腾讯云对象存储的功能。内容包括引入cos-js-sdk-v5,详细封装过程,以及在页面中使用该组件的示例。组件新增了图片过大时的压缩功能,并优化了上传方法,确保上传大小超过80M的图片时能显示进度信息。
摘要由CSDN通过智能技术生成

之前总结过 vue 封装图片上传组件到腾讯云对象存储,后来又加了一些功能,在图片过大时进行压缩,压缩完成之后,再上传到腾讯云对象存储;并且,对上传方法进行了优化,所以重新记录一下。

1、 引入cos-js-sdk-v5

安装 JavaScript SDK

npm install cos-js-sdk-v5

安装成功后会有如下信息:
在这里插入图片描述

2、封装uploadcos.js

新建文件uploadcos.js,封装上传文件方法。

/**
 * 本文件为腾讯云对象存储相关工具类方法
  注意:桶的访问权限需要设置指定域名(不然会出现跨域问题),现在设置允许访问的域名是:
  http://localhost:8080 https://xxx.com.cn/
  所以本地调试时,需要用http://localhost:8080,不可用其他端口。
  跨域配置:
  桶:指定域名 + 指定子账号能上传;外部不能访问,统一通过cdn访问;
  CDN:设置为无跨域限制

  ---- COD自主诊断工具:https://cloud.tencent.com/login?s_url=https%3A%2F%2Fconsole.cloud.tencent.com%2Fcos5%2Fdiagnose -----
 */

// https://cloud.tencent.com/document/product/436/11459
import COS from 'cos-js-sdk-v5'
import {
    Message } from 'element-ui'
import {
    getCOSSecretKey } from '@/api/index'

// 存储桶所在地域
const BUCKET_REGION = 'ap-beijing'
// 使用分片上传阈值10(M)
const SLICE_SIZE = 10

const BUCKET_TYPE_CONFIG = {
   
  video: 'video-b-123456',
  image: 'image-b-123456',
  file: 'file-b-123456'
}

const BUCKET_DOMAIN = {
   
  video: 'https://abcd-video.xxx.com.cn',
  image: 'https://abcd-image.xxx.com.cn'
}

const FOLDER_PATH_NAME = {
   
  // 内容图片
  ART: {
   
    prod: '/art/',
    test: '/test/art/'
  },
  // 日常活动图片
  ACT: {
   
    prod: '/act/',
    test: '/test/act/'
  },
  // 产品图片
  WARE: {
   
    prod: '/ware/',
    test: '/test/ware/'
  },
  // 广告&宣传图片
  ADV: {
   
    prod: '/adv/',
    test: '/test/adv/'
  }
}

/**
 * options @param {Object}
 * sliceSize:使用切片上传阈值 默认10(M)
 * bucketType:桶类型 video,image,file 三种类型
 * busiType:业务类型
 * needLaoding:是否需要loading遮罩层
 * bucketEnv:桶的环境 测试、生产
 * bucketName:桶的名称
 * bucketDomain:桶的域名 用来拼接key
 * bucketPrefix:自定义桶地址前缀片段
 * credentials:后台返回凭证信息
 * keyBackData:后台返回密钥信息 为credentials父级
 */
class Cos {
   
  constructor(options) {
   
    this.bucketEnv =
      window.msBaseUrl === 'https://xxx.com.cn/' ? 'prod' : 'test'
    this.bucketType = options?.bucketType || BUCKET_TYPE_CONFIG.file
    this.bucketName = BUCKET_TYPE_CONFIG[this.bucketType]
    this.bucketDomain = BUCKET_DOMAIN[this.bucketType]
    this.sliceSize = options?.sliceSize || SLICE_SIZE
    this.busiType = options?.busiType || 'ART'
    this.bucketPrefix = FOLDER_PATH_NAME[this.busiType][this.bucketEnv]
    this.credentials = null
    this.keyBackData = null
  }

  /**
   * 获取密钥
   * @returns Object
   */
  async getKey () {
   
    try {
   
      const res = await getCOSSecretKey({
   
        bucket: this.bucketName
      })
      if (
        res?.result?.credentials &&
        Object.keys(res?.result?.credentials).length
      ) {
   
        this.keyBackData = res.result
        this.credentials = res.result.credentials
        return this.credentials
      }
      return null
    } catch (error) {
   
      return null
    }
  }

  /**
   * 生成上传资源名称 6位随机数+uid+文件名
   */

  generateKey (file) {
   
    const timeStamp = file.uid ? file.uid : new Date().getTime() + ''
    const suffix = file.name.split('.')[file.name.split('.').length - 1]
    return `${
     this.randomString()}_${
     timeStamp}.${
     suffix}`
  }

  /**
   * 获取随机数
   * @param {*} len
   * @returns
   */
  randomString (len = 6) {
   
    const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
    const maxPos = chars.length
    let res = ''
    for (let i = 0; i < len; i++) {
   
      res += chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return res
  }

  /**
   * 创建COS对象实例
   * @returns Object
   */
  async getCosInstance () {
   
    const getKey = await this.getKey()
    if (getKey) {
   
      const {
    tmpSecretId, tmpSecretKey, sessionToken } = this.credentials
      const {
    startTime, expiredTime } = this.keyBackData
      const params = {
   
        TmpSecretId: tmpSecretId,
        TmpSecretKey: tmpSecretKey,
        SecurityToken: sessionToken,
        StartTime: startTime,
        ExpiredTime: expiredTime
      }
      const _cos = new COS({
   
        getAuthorization: function (options, callback) {
   
          callback(params)
        }
      })
      return _cos
    }
    return null
  }

  /**
   * 单个文件上传到腾讯云cos
   * @param {*} file
   * @returns
   */
  async uploadHandle (file) {
   
    const cos = await this.getCosInstance()
    if (cos) {
   
      const KEY = `${
     this.bucketPrefix}${
     this.generateKey(
        file
      )}`
      console.log('KEY', KEY)
      return new Promise((resolve, reject) => {
   
        // if (this.needLoading) {
   
        //   var loadingInstance = Loading.service({ fullscreen: true })
        // }

        cos.uploadFile(
          {
   
            Bucket: this.bucketName /* 填入您自己的存储桶,必须字段 */,
            Region: BUCKET_REGION /* 存储桶所在地域,例如ap-beijing,必须字段 */,
            Key: KEY /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */,
            Body: file /* 必须,上传文件对象,可以是input[type="file"]标签选择本地文件后得到的file对象 */,
            SliceSize:
              1024 *
              1024 *
              this
                .sliceSize /* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */,
            onTaskReady: function (taskId) {
   
              /* 非必须 */
              // console.log(taskId)
            },
            onProgress: function (progressData) {
   
              /* 非必须 */
              // console.log(JSON.stringify(progressData))
              const percent = parseInt(progressData.percent * 10000) / 100
              const speed =
                parseInt((progressData.speed / 1024 / 1024) * 100) / 100
              console.log('进度:' + percent + '%; 速度:' + speed + 'Mb/s;')
            },
            onFileFinish: function (err, data, options) {
   
              /* 非必须 */
              console.log(options.Key + '上传' + (err ? '失败' : '完成'))
            }
          },
          (err, data) => {
   
            // loadingInstance && loadingInstance.close()
            if (err) {
   
              Message.error(err)
              reject(err)
            }
            const url = `${
     this.bucketDomain}${
     KEY
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值