基于ElementUI上传腾讯云Cos,上传组件进行自定义封装

2019-07-17  本文已影响0人  jumper996

1.效果图

image.png
image.png

2.使用方式

<sy-upload v-model="form.thumbnail" bucket="Private" title="请选择缩略图" folder-name="/default-folder"></sy-upload>

3.首先编写sy-upload.vue

<style scoped>
  .avatar-uploader .el-upload {
    border: 1px solid #f3f3f8;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #f3f3f8;
  }
  .avatar-uploader-icon {
    font-size: 20px;
    color: #8c939d;
    width: 150px;
    height: 150px;
    line-height: 150px;
    text-align: center;
    border: 1px solid #ccc;
  }
  .sy-up-avatar {
    width: 150px;
    height: 150px;
    display: block;
  }
  .sy-preview-img {
    width: 150px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }
</style>
<template>
  <div>
    <el-upload
      :style="{width: (width)+'px', height: (height)+'px'}"
      class="avatar-uploader"
      :action="uploadFileUrl"
      :show-file-list="false"
      :multiple="false"
      :limit="1"
      :data="params"
      :on-success="handleSuccess"
      :before-upload="handleBeforeUpload">
      <img v-if="imageUrl" :src="imageUrl" class="sy-up-avatar">
      <div v-else class="avatar-uploader-icon">{{title}}</div>
    </el-upload>
    <div class="sy-preview-img" v-if="showPreview || showRemove">
      <el-button v-if="showPreview && imageUrl!=''" type="primary" size="mini" @click="preview()">预览</el-button>
      <el-button v-if="showRemove && imageUrl!=''" type="danger" size="mini" @click="remove()">移除</el-button>
    </div>

    <el-dialog :modal="false" @close="closePreview" :visible="previewVisible">
      <img width="100%" :src="this.imageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
    /**
      * 存储桶Cos内容
        const bucket = {
            Private: 'https://private-xxxx.cos.ap-xxxx.myqcloud.com',
            Protected: 'https://protected-xxxx.cos.ap-xxxx.myqcloud.com',
            Public: 'https://public-xxxx.cos.ap-xxxx.myqcloud.com',
        }
      */
    import Cos from '@/util/cosUpload'
    import CosApi from '@/api/file/cos'
    export default {
      props: {
        width: {
          type: Number,
          default: 150,
        },
        height: {
          type: Number,
          default: 150,
        },
        bucket: {
          type: String,
          default: 'Private',
        },
        title: {
          type: String,
          default: '请选择图片',
        },
        folderName: {
          type: String,
          default: '/default-folder',
        },
        showRemove: {
          type: Boolean,
          default: true,
        },
        showPreview: {
          type: Boolean,
          default: true,
        },
        value: {
          type: String,
          default: '',
        },
      },
      name: "sy-upload",
      data: function () {
        return {
          show: false,
          uploadFileUrl: '',
          imageUrl: this.value,
          params: {},
          previewVisible: false
        }
      },
      watch: {
        imageUrl (newVal) {
          // 绑定v-model的值更新
          this.$emit('input', newVal)
        },
        value (newVal) {
          // 绑定父组件的值更新子组件
          this.imageUrl = newVal
        }
      },
      mounted () {
        setTimeout(() => {
          let _this=this;
          _this.$nextTick(function () {
            this.init()
          })
        }, 200)
      },
      methods: {
        init () {
          // 上传路径设置,根据不同的bucket获取不同的上传路径,这里自定义
          this.uploadFileUrl = Cos.bucket[this.bucket]
          this.$nextTick(function () {
            this.show = true
          })
        },
        async handleBeforeUpload (file) {
          // 同步进行build参数
          await this.buildParams(file)
          return true
        },
        handleSuccess (res) {
          // 成功之后重新签名url
          CosApi.urlSign(this.params.url).then(res => {
            this.imageUrl = res.data.data
          })
        },
        async buildParams (file) {
          // 上传之前需要的额外参数设置
          let fd = {};
          let idx = file.name.lastIndexOf(".");
          let suffix = "";
          if (idx > 0) {
            suffix = file.name.substring(idx);
          }
          let key = this.folderName + "/" + Date.parse(new Date()) + Math.floor(Math.random() * 10000000 + 1) + suffix

          let info = await CosApi.sign(
            this.bucket,
            key
          );
          info = info.data.data
          fd["x-cos-security-token"] = info.XCosSecurityToken;
          fd["Signature"] = info.Authorization;
          fd["key"] = key;
          fd["url"] = info.url;
          fd["bucketName"] = info.bucketName;
          this.params = fd
          return fd;
        },
        preview () {
          this.previewVisible = true
        },
        closePreview () {
          this.previewVisible = false
        },
        remove () {
          this.imageUrl = ''
        },
      }
    }
</script>

4.编写安装syUpload.js

import SyUpload from "@/components/upload/sy-upload"

export default {
  install (Vue) {
    Vue.component('SyUpload', SyUpload)
  }
}

5.在main.js中全局注册

import SyUpload from "@/util/syUpload"
Vue.use(SyUpload)

6.参数说明

props: {
  // 宽
  width: {
    type: Number,
    default: 150,
  },
  // 高
  height: {
    type: Number,
    default: 150,
  },
  // 存储桶  Private Protected Public 
  bucket: {
    type: String,
    default: 'Private',
  },
  // 标题
  title: {
    type: String,
    default: '请选择图片',
  },
  // 上传存储桶位置
  folderName: {
    type: String,
    default: '/default-folder',
  },
  // 是否显示移除按钮
  showRemove: {
    type: Boolean,
    default: true,
  },
  // 是否显示预览
  showPreview: {
    type: Boolean,
    default: true,
  },
},
上一篇下一篇

猜你喜欢

热点阅读