Vue图片上传压缩(放大左右滑动)

1 篇文章 0 订阅
1 篇文章 0 订阅

Vue图片上传压缩(放大左右滑动)

描述: 早在17年入行的时候就有需求做图片上传,其实很简单几个步骤就可以搞定

  • 备注: 样式采用计算px转rem
  • 主要效果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

主要步骤

文件上传
图片压缩
放大滑动

  • 涉及input,canvas,swiper

dom

<template>
  <!--轮播-->
  <div class="upload">
    <div class="upload_img">
      <div class="img_list" v-for="(item, index) in imgList" :key="index" @click="scaleLargeSwiper(index)">
        <img class="img_close" src="../../../assets/image/common/close.png" @click="delImg(index, $event)">
        <img class="img" :src="item">
      </div>
      <div class="img_list upload_line" v-if="imgList.length < maxImgLength">
        <span>+</span>
        <input ref="input" type="file" name="file" accept="image/*" multiple="multiple" @input="handleFileChange">
      </div>
    </div>
    <!--轮播-->
    <swiper v-if="isShowSwiper"
            @closeModel="closeModel"
            :imgList="imgList"
            :defaultIndex="defaultIndex"></swiper>
  </div>
</template>

js

<script>
import swiper from "./swiper";
export default {
  name: "upload",
  components: {swiper},
  props: {
    // 按钮文字
    btnTitle: {
      default: '',
      type: String
    },
    // 最大图片数
    maxImgLength: {
      default: 5,
      type: Number
    },
    // 默认已有图片
    outImgList: {
      type: Array,
      default() {
        return []
      }
    },
    // 最大上传
    maxSize: {
      default: 2,
      type: Number
    },
    text: {
      default: ''
    }
  },
  data(){
    return {
      // 图片最大宽度
      maxWidth: 1000,
      // 图片最大高度
      maxHeight: 1000,
      // 图片集合
      imgList: [],
      // 是否显示轮播
      isShowSwiper: false,
      // 默认显示索引
      defaultIndex: 0,
      // 显示loading
      isLoading: false
    }
  },
  created() {
    this.imgList = [...this.outImgList]
  },
  methods: {
    // 选择图片处理
    handleFileChange() {
      let files = this.$refs.input.files
      let size,
        len = files.length > this.maxImgLength ? this.maxImgLength : files.length
      for (let i = 0; i < len; i++) {
        size = files[i].size / 1024 / 1024
        let FR = new FileReader()
        FR.readAsDataURL(files[i]);
        FR.onload = (e) => {
          // 大于2M
          if (Math.floor(size) > 2) {
            this.checkImgSize(e.target.result)
          } else {
            this.imgList.push(e.target.result)
            this.$emit('addImg', this.imgList)
          }
        }
      }
    },
    // 校验图片大小
    checkImgSize(url) {
      let img = new Image()
      img.src = url
      img.onload = () => {
        let { width: originW, height: originH } = img
        if (originW > this.maxWidth || originH > this.maxHeight) {
          if (originW > originH) {
            //宽大于高
            let rat = Math.ceil(originW / this.maxWidth),
             targetW = Math.floor(originW / rat), //目标的宽度
             targetH = Math.floor(originH / rat) //目标的高度
            this.imgPress(img, targetW, targetH )
          } else {
            //高大于宽
            Let rat = Math.ceil(originH / this.maxHeight),
             targetW= Math.floor(originW / rat),
             targetH = Math.floor(originH / rat)
            this.imgPress( img, targetW, targetH )
          }
        }
      }
    },
    // 图片压缩
    imgPress(img, w, h) {
      let canvas = document.createElement('canvas’),
       ctx = canvas.getContext('2d’),
       anw = document.createAttribute('width’),
       anh = document.createAttribute('height')
      anw.nodeValue = w
      anh.nodeValue = h
      canvas.setAttributeNode(anw)
      canvas.setAttributeNode(anh)
      ctx.drawImage(img, 0, 0, w, h)
      let base64 = canvas.toDataURL('image/jpeg', 0.9)
      this.imgList.push(base64)
      this.$emit('addImg', this.imgList)
    },
    // 删除图片
    delImg(index, e) {
      e.stopPropagation()
      this.imgList.splice(index, 1)
      this.$refs.input && (this.$refs.input.value = null)
      this.$emit('delImg', this.imgList)
    },
    // 放大轮播
    scaleLargeSwiper(id) {
      this.isShowSwiper = true
      this.defaultIndex = id
    },
    // 关闭model
    closeModel(bool) {
      this.isShowSwiper = bool
    }
  }
}
</script>
> less
<style scoped lang="less">
// 上传及描述
.upload {
  // 上传图片
  .upload_img {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    .img_list {
      margin-top: 24px;
      width: 160px;
      height: 160px;
      overflow: hidden;
      margin-right: 20px;
      position: relative;
      .img_close {
        position: absolute;
        top: 0;
        right: 0;
        width: 34px;
        height: 34px;
      }
      .img {
        width: 160px;
        height: 160px;
        border-radius: 8px;
        display: block;
      }
    }
    .img_list:nth-child(3n) {
      margin-right: 0;
    }
  }
  .upload_line {
    border: 1px dashed #CCCCCC;
    border-radius: 8px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    input {
      width: 160px;
      height: 160px;
      position: absolute;
      opacity: 0;
    }
    span{
      color: #969798;
      font-size: 100px;
    }
  }
}
</style>

引用

<template>
	<section>
		<upload @addImg="addImg" @delImg="delImg"></upload>
	</section>
</template>

<script>
import upload from './common/upload'

export default {
  components: {upload},
data(){
	return {
		imgList: []
	}
},
  methods: {
	// 删除图片
delImg(imgList){
  this.imgList = imgList
},
// 新增图片
addImg(imgList){
  this.imgList = imgList
}

  }

}
</script>

整体来说还是比较容易实现简单的图片上传,此外你还可以做其他操作,比如放大之后的缩放,上传之后base64转Blob等

具体代码具体见[ https://github.com/FrontWalker2000/self-vue-sys ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值