基于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>
参考: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

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

补充:

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

相关推荐

  1. 基于element-plus +COS实现图片

    2024-03-18 16:52:01       17 阅读
  2. vue、thinkphp实现对象存储COS图片

    2024-03-18 16:52:01       26 阅读
  3. python3实现gitlab备份文件COS

    2024-03-18 16:52:01       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-18 16:52:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-18 16:52:01       20 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-18 16:52:01       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-18 16:52:01       20 阅读

热门阅读

  1. mysql 从某个字段中截取某部分

    2024-03-18 16:52:01       21 阅读
  2. 动态规划基础知识点(包含文档)

    2024-03-18 16:52:01       23 阅读
  3. C语言—计算输入的字符串中数字、字符等的数量

    2024-03-18 16:52:01       22 阅读
  4. pta7-25 念数字 C语言

    2024-03-18 16:52:01       21 阅读
  5. C语言中的变量范围规定方法

    2024-03-18 16:52:01       17 阅读
  6. LeetCode(力扣)算法题_2789_合并数组后的最大元素

    2024-03-18 16:52:01       20 阅读
  7. postgresql查看数据库占用空间大小

    2024-03-18 16:52:01       20 阅读
  8. MySQL

    MySQL

    2024-03-18 16:52:01      18 阅读
  9. 记录使用vue3自定义指令

    2024-03-18 16:52:01       21 阅读
  10. MyBatisPlus 之五:MP 的 IService 接口实现方式

    2024-03-18 16:52:01       20 阅读
  11. Python常用内置函数

    2024-03-18 16:52:01       21 阅读
  12. LeetCode刷题笔记之动态规划(二)

    2024-03-18 16:52:01       21 阅读
  13. mysql判断一个字符串字段的长度是否为0

    2024-03-18 16:52:01       15 阅读
  14. css的严格模式和混杂模式区别?

    2024-03-18 16:52:01       25 阅读