当前位置:   article > 正文

基于element-plus +腾讯云COS实现图片上传

基于element-plus +腾讯云COS实现图片上传

① 首先基于element-plus里面的:http-request="upload"自定义封装事件写一个点击事件之后基于腾讯云的

  1. 登录 对象存储控制台 ,创建存储桶。获取存储桶名称和 地域名称
  2. 登录 访问管理控制台 ,获取您的项目 SecretId 和 SecretKey。
  3. 在项目中安装 SDK 【npm i cos-js-sdk-v5 --save】
  4. 使用 const COS = require(‘cos-js-sdk-v5’);// 或 import COS from ‘cos-js-sdk-v5’;进行引入
  5. 前端使用固定密钥计算签名,该格式适用于前端调试,若使用此格式,请避免泄露密钥

【这里还有一些推荐的方法具体见 https://cloud.tencent.com/document/product/436/11459 】

  1. 当我们获取SecretKey 和 SecretId之后在定义的upload上传方法中调用 cos.uploadFile实现图片上传

腾讯云的相关操作:【https://cloud.tencent.com/document/product/436/11459】

// 代码:
<template>
  <div class="upload-box">
    <!-- 给action一个#号 就不会报错了 -->
    <!-- file-list是上传的文件列表 可以绑定到上传组件上,让上传组件来显示 -->
    <!-- upload组件显示的是file-list -->
    <el-upload 
    class="avatar-uploader" 
    list-type="picture-card" 
    :limit="1" action="#" 
    :before-upload="beforeUpload"
    :http-request="upload" 
    :on-preview="preview" 
    :file-list="state.fileList"
    style="width: 200px"
    :on-change="changeFile"
    :class="{ disabled: fileComputed }">
      <!-- 当fileComputed 的值为 true,则给元素添加名为 "disabled"CSS 类名;如果 fileComputed的值为 false,则移除该 CSS 类名。 -->
    </el-upload>
    <el-dialog v-model="state.showDialog" title="图片预览">
      <img :src="state.imgUrl" alt="" style="width: 100%" />
    </el-dialog>
  </div>
</template>

<script setup>
import { reactive, computed } from "vue"
import COS from "cos-js-sdk-v5" // 引入腾讯云cos包
import { ElMessage } from "element-plus"
// 实例化COS对象
const cos = new COS({
  // 拷贝自己的秘钥和key 只有用自己的key和自己的秘钥才能上传到自己的存储桶里面
  SecretId: "自己的身份识别ID", // 身份识别 ID
  SecretKey: "自己的身份秘钥", // 身份密钥
})

const state = reactive({
  fileList: [],
  showDialog: false,
  imgUrl: "",
  currentFileUid: null, // 记录当前正在上传的uid
})
const fileComputed = computed(() => {
  return state.fileList.length === 1
})

//   点击预览事件
const preview = (file) => {
  console.log(file.url)
  state.imgUrl = file.url
  state.showDialog = true
}


const beforeUpload = (file) => {
  const types = ["image/jpeg", "image/gif", "image/bmp", "image/png"]
  if (!types.some((item) => item === file.type)) {
    //   如果不存在
    ElMessage.error("上传图片只能是 JPG、GIF、BMP、PNG 格式!")
    return false // 上传终止
  }
  // 检查文件大小  5M 1M = 1024KB 1KB = 1024B
  const maxSize = 10 * 1024 * 1024
  if (file.size > maxSize) {
    //   超过了限制的文件大小
    ElMessage.error("上传的图片大小不能大于5M")
    return false
  }
  //   已经确定当前上传的就是当前的这个file了
  state.currentFileUid = file.uid
  return true // 最后一定要return  true
}
// changeFile 函数的主要作用是在文件列表发生变化时,根据最新的文件列表更新 state.fileList,保持数据的同步和一致性。
// 这样可以确保组件在文件变化时能够及时更新展示的内容。如果有任何疑问或需要进一步解释,请随时告诉我!
// 不能用push 这个钩子会执行多次
const changeFile = (file, fileList) => {
  // file是当前的文件 fileList是当前的最新数组 state.fileList
  // 如果当前fileList中没有该文件的话 就往里进行追加
  state.fileList = fileList.map((item) => item)
}
// 进行上传操作
const upload = (params) => {
  if (params.file) {
    // 执行上传操作
    // 这里相当于传入了两个参数 第一个参数包含了上传所需要的参数,第二个参数是一个回调函数用于处理上传操作的结果
    // 包括错误信息和上传成功后的返回数据
    cos.putObject(
      {
        Bucket: "存储桶名称", // 存储桶    【自己创建的桶的名称】
        Region: "ap-nanjing", // 地域 【自己创建的时候选择的地域】
        Key: params.file.name, // 文件名
        Body: params.file, // 要上传的文件对象
        StorageClass: "STANDARD", // 上传的模式类型 直接默认 标准模式即可
      },
      (err, data) => {
        if (!err && data.statusCode === 200) {
          // 上传成功跟新状态中的文件列表
          state.fileList = state.fileList.map((item) => {
            // 去找谁的uid等于刚刚记录下来的id
            if (item.uid === state.currentFileUid) {
              // 将成功的地址赋值给原来的url属性
              return { url: "http://" + data.Location, upload: true }
            }
            return item
          })
        }
      }
    )
  }
}
</script>

<style>
.upload-box {
  display: block;
  width: 200px;
  margin: 0 auto;
}


.disabled .el-upload--picture-card {
  display: none;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
参考:https://cloud.tencent.com/document/product/436/64960#.E9.AB.98.E7.BA.A7.E4.B8.8A.E4.BC.A0
  https://juejin.cn/post/7093678563747954696
  • 1

注意: 我们在使用cos进行上传的时候需要创建桶,获取秘钥等操作
创建存储桶 【https://cloud.tencent.com/document/product/436/13309 创建存储桶的具体操作】文档中心-左侧创建存储桶
获取秘钥的具体操作 【https://cloud.tencent.com/document/product/598/40488】
–>

补充:

在代码中,如果直接使用 push 方法将文件对象添加到 state.fileList 中,这会导致数组的长度发生变化,
从而触发 Vue 的响应式机制。当触发响应式更新时,changeFile 方法会再次被调用,进而导致多次执行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/262797
推荐阅读