基于element-ui封装上传图片到腾讯云Cos组件

Posted SpaceX7_s

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于element-ui封装上传图片到腾讯云Cos组件相关的知识,希望对你有一定的参考价值。

组件需求

上传图片到腾讯云Cos服务器

  1. 可以显示传入的图片地址
  2. 可以删除传入的图片地址
  3. 可以上传图片到云服务器
  4. 上传到腾讯云之后,可以返回图片地址,显示
  5. 上传成功之后,可以回调成功函数

    需要使用借助一个插件,帮助我们上传图片资源到腾讯云Cos
npm i cos-js-sdk-v5 --save

使用element的el-upload组件上传本地图片

<template>
 <el-upload list-type="picture-card" :limit="1" action="#">
  </el-upload>
</template>

limt 限制图片上传的数量
action=“#” 使用自定义上传方式,所以取消它的默认上传方法

添加弹层图片预览功能
 <el-dialog title="图片" :visible.sync="showDialog">
      <img :src="imgUrl" style="width:100%" alt="">
   </el-dialog>

完成代码

<template>
  <div>
    <el-upload
      :on-preview="preview"
      :on-remove="handleRemove"
      :on-change="changeFile"
      :before-upload="beforeUpload"
      :file-list="fileList"
      list-type="picture-card"
      action="#"
      :limit="1"
      :class=" disabled: fileComputed "
      :http-request="upload"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-progress
      v-if="showPercent"
      style="width: 180px"
      :percentage="percent"
    />
    <el-dialog title="图片" :visible.sync="showDialog">
      <img :src="imgUrl" style="width: 100%" alt="" />
    </el-dialog>
  </div>
</template>
<script>
import COS from "cos-js-sdk-v5";
var cos = new COS(
   //腾讯云的id和密码
  SecretId: "AKIDVHoxxxxx", // 身份识别 ID
  SecretKey: "uWrxxxxx", // 身份密钥
);
export default 
  name: "ImageUpload",
  data() 
    return 
      fileList: [], // 图片地址设置为数组
      showDialog: false, // 控制显示弹层
      imgUrl: "",
      currentFileUid: null, //确定上传图片的id
      showPercent: false, //状态加载条
      percent: 0,//进度条加载过程
    ;
  ,
  computed: 
    // 设定一个计算属性 判断是否已经上传完了一张
    fileComputed() 
      return this.fileList.length === 1;
    ,
  ,
  methods: 
    //预览图片时的回调
    preview(file) 
      this.imgUrl = file.url; //点击预览时,传递图片地址给弹出层
      this.showDialog = true;
    ,
    //删除图片的回调
    handleRemove(file) 
      // file是点击删除的文件
      //   将原来的文件给排除掉了 剩下的就是最新的数组了
      this.fileList = this.fileList.filter((item) => item.uid !== file.uid);
    ,
    // 修改文件时触发
    // 此时可以用fileList 因为该方法会进来很多遍 不能每次都去push
    // fileList因为fileList参数是当前传进来的最新参数 我们只需要将其转化成数组即可 需要转化成一个新的数组
    // [] => [...fileList] [] => fileList.map()
    // 上传成功之后 还会进来 需要实现上传代码的逻辑 这里才会成功
    /* 
    文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
    */
    changeFile(file, fileList) 
      this.fileList = fileList.map((item) => item);
    ,
    //上传之前检查
    beforeUpload(file) 
      // 要开始做文件上传的检查了
      // 文件类型 文件大小
      const types = ["image/jpeg", "image/gif", "image/bmp", "image/png"];

      /*  if (!types.includes(file.type)) 
        this.$message.error('上传图片只能是 JPG、GIF、BMP、PNG 格式!')
        return false
       */
      if (!types.some((item) => item === file.type)) 
        //此时说明上传的类型不是规定类型
        this.$message.warning("上传图片只能是 JPG、GIF、BMP、PNG 格式!");
        return false; //停止上传
      
      //  检查大小
      //1mb 等于 1024KB 1KB=1024B
      //限制大小为5mb
      const maxSize = 5 * 1024 * 1024;
      if (maxSize < file.size) 
        this.$message.error("图片大小最大不能超过5M");
        return false;
      
      //此时upload组件会为文件对象生成一个id属性

      this.currentFileUid = file.uid;
      //显示加载进度条
      this.showPercent = true;
      return true;
    ,
    // 自定义上传动作 有个参数 有个file对象,是我们需要上传到腾讯云服务器的内容
    // 进行上传操作
    upload(params) 
      //   console.log(params.file)
      if (params.file) 
        // 执行上传操作
        cos.putObject(
          
            Bucket: "web07-7-1311561617", // 存储桶
            Region: "ap-guangzhou", // 地域
            Key: params.file.name, // 文件名
            Body: params.file, // 要上传的文件对象
            StorageClass: "STANDARD", // 上传的模式类型 直接默认 标准模式即可
            // 上传到腾讯云 =》 哪个存储桶 哪个地域的存储桶 文件  格式  名称 回调
            onProgress: (params) => 
              this.percent = params.percent * 100;
            ,
          ,
          (err, data) => 
            // 这个回调需要使用箭头函数,因为currentFileUid在当前组件实例对象上,
            //箭头函数没有this,会继承upload方法的this,它的this执行vue组件实例

            // data中有一个statusCode === 200 的时候说明上传成功
            if (!err && data.statusCode === 200) 
              //   此时说明文件上传成功  云服务器会返回一个地址,我们需要把该地址放到组件的img标签上
              //  此时我们要将fileList中的数据的url地址变成 现在上传成功的地址
              // 目前虽然是一张图片 但是请注意 我们的fileList是一个数组
              // 需要知道当前上传成功的是哪一张图片
              this.fileList = this.fileList.map((item) => 
                // 去找谁的uid等于刚刚记录下来的id
                if (item.uid === this.currentFileUid) 
                  //Location为传回的地址,但是没有http字段
                  // 将成功的地址赋值给原来的url属性

                  return  url: "http://" + data.Location, upload: true ;

                  // upload 为true 表示这张图片已经上传完毕 这个属性要为我们后期应用的时候做标记
                  // 保存  => 图片有大有小 => 上传速度有快又慢 =>要根据有没有upload这个标记来决定是否去保存
                
                return item;
              );
              // 将上传成功的地址 回写到了fileList中 fileList变化  =》 upload组件 就会根据fileList的变化而去渲染视图
              setTimeout(() => 
                this.showPercent = false; // 隐藏进度条
                this.percent = 0; // 进度归0
              , 1000);
            
          
        );
      
    ,
  ,
;
</script>

<style lang="less" scoped>
.disabled 
    //当有一个图片时,上传按钮不再显示
  /deep/.el-upload--picture-card 
    display: none;
  

</style>

在使用该组件是,获取图片的时候,如果数据库返回的图片的地址,那么也应该放回该组件的fileList数组,那么该组件才能显示图片,在上传图片保存到数据库端时,是先上传到腾讯云服务器,返回图片地址,把图片地址放入数据库中,那么就实现了图片的上传功能

   //保存员工图片
    async savePersonal() 
       //通过ref获取上传图片的子组件,并获取存放图片的数组
       const fileList = this.$refs.myStaffPhoto.fileList; // 读取上传组件的数据
      if (fileList.some((item) => !item.upload)) 
        //  如果此时去找 upload为false的图片 找到了说明 有图片还没有上传完成
        this.$message.warning("您当前还有图片没有上传完成!");
        return;
      
      await updatePersonal(
        ...this.formData,
        staffPhoto: fileList && fileList.length ? fileList[0].url : " ", //接口规定如果没有上传图片就传一个空空字符串
      );
      this.$message.success("保存基础信息成功");
    ,
    //获取员工照片
    //从数据库获取回来的数据如果有员工图片,那么也展示到上传的子组件上
    async getPersonalDetail() 
      this.formData = await getPersonalDetail(this.userId); // 获取员工数据
      //使用trim()是因为如果没有图片返回的是一个空格
      if (this.formData.staffPhoto && this.formData.staffPhoto.trim()) 
        /*  this.$refs.staffPhoto.fileList.push(
          url:this.userInfo.staffPhoto,upload: true
        ) */
        this.$refs.myStaffPhoto.fileList = [
           url: this.formData.staffPhoto, upload: true ,
        ];
      
    ,

以上是关于基于element-ui封装上传图片到腾讯云Cos组件的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序上传图片到COS腾讯云

小程序开发:上传图片到腾讯云

vue.js+云存储(实现图片上传功能)

vue.js+云存储(实现图片上传功能)

如何在typecho中使用腾讯云对象存储cos?

上传图片到腾讯云