vue 图片上传并压缩

在这里插入图片描述
在这里插入图片描述

<template>
    <div id="vue-img-uploader">
        <input type="file"
        accept="image/*"
        :id="componentId"
       
        @change="getFile">
        <template v-if="files.length>0">
            <div class="vue-thumbnail-wrapper" v-for="(img,index) in files" :key="index">
                <div class="del-button" @click="deleteImg(img.name,index)">
                  <img src="@/assets/img/delete.png" alt="">
                </div>
                <img class="vue-img-thumbnail" :data-index="index" :src="img.imageUrl">
            </div>
        </template>
        <div class="loading" v-show="loading">
            <div class="donut"></div>
        </div>
        <label :for="componentId" v-if="files.length<max && !loading">
            <div class="default" v-if="!$slots.addButton">
              <img src="@/assets/img/add_img.png" alt="">
            </div>
            <p v-if="files.length==0" class="default_p">请上传清晰的问题照片,以方便快速解决问题(图片大小2M以内)</p>  
        </label>
    </div>
</template>

<script>
import ImageCompressor from 'image-compressor.js'
export default {
  data() {
    return {
      files: [], // 展示用列表
      formData: new FormData(), // 上传用列表
      loading: false,
      max:9,
      maxSize: 2 * 1024 * 1024,//限制上传图片大小为2M
      compressQuality:0.6,
      autoUpload:true,
      initialImg:[],
      qiniuDomain: "",
      QiniuData: {
        token: "",
      },
    }
  },
  props: {
    componentId:{
      type:String,
      default:'cid' + Math.floor(Math.random() * 10000),
      validator: function (value) {
        let hasNotWord = /\W/.test(value)
        return !hasNotWord
      }
    }
  },
  mounted() {
    this.$qiniuUtil.Init(this);
  },
  watch: {
  
  },
  methods: {
    async getFile(evt) {
      var _this = this;
      let file = evt.target.files[0];
      let compreeBolb = await _this.imgCompress(file);
      let fileName = compreeBolb.name;
      if(compreeBolb.size>this.maxSize){
        this.$toast({
          message:"请上传2M以内图片"
        })
        return
      }
      this.loading = true
      document.querySelector(`#${this.componentId}`).value = null;
      this.$qiniuUtil.uploadFile(compreeBolb, this, function(url){
        _this.files.push({"imageUrl": url })
      });

      // 新增图片加入展示列表
      this.$emit('updateImg', this.files);
      this.loading = false
    },
    deleteImg(name, index) {
      this.files.splice(index, 1);
      this.formData.delete(name);
      this.$emit('updateImg', this.files);
    },
    getDataURL(file) {
      return new Promise((res, rej) => {
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = evt => res(evt.target.result)
        reader.onerror = err => rej(err)
      })
    },
    imgCompress(file) {
      return new Promise((res, rej) => {
        new ImageCompressor(file, {
          quality: this.compressQuality,
          success(result) {
            res(result)
          },
          error(err) {
            rej(err)
          }
        })
      })
    },
  }
}
</script>

<style scoped lang="scss">
#vue-img-uploader {
  display: flex;
  flex-wrap: wrap;
}
.vue-thumbnail-wrapper {
  position: relative;
  margin-right:0.34rem;
  margin-bottom:0.34rem;
  border-radius: 8px;
}
.vue-thumbnail-wrapper> img{
  display: block;
  height: 1.52rem;
  width: 1.52rem;
  object-fit: cover;
   border-radius: 8px;

}
.del-button {
  position: absolute;
  margin: 5px;
  top: -0.06rem;
  right:-0.05rem;
  border-radius: 50%;
  width: 0.5rem;
  height: 0.5rem;
  line-height: 15px;
  text-align: center;
  img{
      width: 0.5rem;
      height: 0.5rem;
  }
}


.loading {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #ccc;
  height: 100px;
  width: 100px;
  margin-right: 10px;
}
.vue-thumbnail-wrapper:nth-child(4n+1){
  margin-right:0;
}
@keyframes donut-spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.donut {
  display: inline-block;
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-left-color: #888;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  animation: donut-spin 1.2s linear infinite;
}
label>.default {
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0.3rem;
  height: 1.52rem;
  width: 1.52rem;
  img{
      width:100%;
      height: 100%;
      vertical-align:middle;
  }
}
input {
  position: absolute;
  top: -10rem;
  left: 0;
}
.default_p{
  font-family: PingFangSC-Regular;
  font-size:0.3rem;
  width: 4.5rem;
  text-align: left;
  color: #999999;
  display: inline-block;
  margin-left:0.3rem;

  position: absolute;
  top:0.5rem;
  left:1.6rem;
}
</style>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值