VUE3 原生JS上传图片(支持多张上传)并实现预览删除功能

本文介绍了使用Vue.js实现的一个图片上传组件,包括文件上传、图片预览、数量限制以及删除功能。展示了如何使用ref和事件处理来管理图片数组和用户交互。
摘要由CSDN通过智能技术生成
<template>
  <!-- 上传后显示 -->
  <div id="look">
    <div id="look_img" v-for="(item, index) in imgSrc" :key="index">
      <img :src="item" alt="">
      <div id="look_event">
        <img src="https://s1.ax1x.com/2022/08/08/vMEtPO.png" alt="" title="点击查看" @click="look(index)">
        <img src="https://s1.ax1x.com/2022/08/08/vMEaxH.png" alt="" title="点击删除" @click="deletes(index)">
      </div>
    </div>
    <!-- 上传图片按钮 -->
    <div id="demo" v-show="uploadnum">
      <input type="file" id="demo_file" accept="image/png,image/gif,image/jpeg" multiple @change="update($event)">
      <img src="https://s1.ax1x.com/2022/08/08/vMEwMd.png" alt="" id="demo_img">
    </div>
  </div>
 
 
  <!-- 图片预览 -->
  <div id="preview" v-if="show" @click="() => { show = false }">
    <div id="preview_close">
      <img src="https://s1.ax1x.com/2022/08/08/vMEURe.png" alt="" title="关闭" @click="() => { show = false }">
    </div>
    <div id="preview_last" v-if="pvwWhere != 0" @click.stop="previewLast()">
      <img src="https://s1.ax1x.com/2022/08/08/vMEBqI.png" alt="" title="上一张">
    </div>
    <div id="preview_next" v-if="pvwWhere != imgSrc.length - 1" @click.stop="previewNext()">
      <img src="https://s1.ax1x.com/2022/08/08/vMErZt.png" alt="" title="下一张">
    </div>
    <img :src="pvwSrc" alt="">
  </div>
 
 
 
 
 
 
</template>
 
<script>
 
import { ref } from "vue";
import { reactive } from "vue";
 
 
export default {
  setup() {
 
    const imgSrc = ref([]);//已上传图片数组
    const arrLength = ref(9);//上传图片数量
    const uploadnum = ref(true);//控制上传按钮的显示隐藏
    const show = ref(false);//控制预览图片遮罩层显示隐藏
    const pvwSrc = ref(null);//预览图片地址
    const pvwWhere = ref(0);//选择哪一张进行预览以及控制上一张下一张
 
 
 
    const update = (e) => {
      let file = e.target.files;
      let filesLength = arrLength.value - imgSrc.value.length;
      for (let i = 0; i < filesLength; i++) {
        let img = new FileReader();
        img.readAsDataURL(file[i]);
        img.onload = ({ target }) => {
          imgSrc.value.push(target.result); //将img转化为二进制数据
          panduan();
        };
      };
    };
    //判断照片数量是否满足规定数量;满足则隐藏上传按钮
    const panduan = () => {
      if (imgSrc.value.length >= arrLength.value) {
        uploadnum.value = false;
      } else {
        uploadnum.value = true;
      }
    };
    panduan();
    //删除图片
    const deletes = (i) => {
      imgSrc.value.splice(i, 1);
      panduan();
    };
    //图片预览
    const look = (i) => {
      console.log(imgSrc.value);
      pvwWhere.value = i;
      show.value = true;
      pvwSrc.value = imgSrc.value[pvwWhere.value]
    };
    //预览:上一张功能
    const previewLast = () => {
      pvwWhere.value--;
      pvwSrc.value = imgSrc.value[pvwWhere.value]
    };
    //预览:下一张功能
    const previewNext = () => {
      pvwWhere.value++;
      pvwSrc.value = imgSrc.value[pvwWhere.value]
    }
 
    return {
      update,
      imgSrc,
      arrLength,
      uploadnum,
      deletes,
      look,
      show,
      pvwSrc,
      pvwWhere,
      previewLast,
      previewNext,
    }
  }
}
</script>
 
 
<style>
#demo {
  width: 20vh;
  height: 20vh;
  position: relative;
  border: 3px dashed #dcdcdc;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-left: 1em;
  margin-top: 1em;
}
 
#demo_file {
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}
 
#demo_img {
  display: block;
  width: 50%;
  height: 50%;
}
 
#look {
  width: 70vh;
  display: flex;
  flex-wrap: wrap;
  justify-content: left;
  align-items: center;
}
 
#look_img {
  width: 20vh;
  height: 20vh;
  margin-left: 1em;
  margin-top: 1em;
  display: flex;
  justify-content: space-around;
}
 
#look_img img {
  display: block;
  width: 20vh;
  height: 20vh;
  cursor: pointer;
}
 
#look_event {
  background: rgba(0, 0, 0, 0.6);
  width: 20vh;
  height: 0px;
  position: absolute;
  transition: 1s;
  display: flex;
  justify-content: center;
  align-items: center;
}
 
#look_event img {
  display: block;
  width: 2em;
  height: 0em;
  cursor: pointer;
}
 
#look_img:hover #look_event {
  height: 20vh;
  /* opacity: 50%; */
}
 
#look_img:hover #look_event>img {
  height: 2em;
}
 
#preview {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
}
 
#preview img {
  width: 40%;
}
 
#preview_close {
  position: absolute;
  top: 4vh;
  right: 0;
  display: flex;
  justify-content: center;
}
 
#preview_last {
  position: absolute;
  left: 0;
  top: 50%;
  display: flex;
  justify-content: center;
}
 
#preview_next {
  position: absolute;
  right: 0;
  top: 50%;
  display: flex;
  justify-content: center;
}
</style>

有不足的地方请随时指出

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值