Vue3实现图片拖曳上传组件
发布者:admin 发表于:451天前 阅读数:813 评论:0

作者用Vue3实现图片拖曳上传组件功能,非常实用

<template>
    <div class="upload-wrapper">
        <div class="item-wrapper landscape"
      :id="item.id"
      v-for="item in data.photos" :key="item.id"
      draggable="true"
      @dragstart.stop="funcs.drag($event)"
      @dragend="funcs.dragend($event)"
      @dragover="funcs.dragover(item.id,$event)"
      @dragleave="funcs.dragleave(item.id)"
      @drop="funcs.drop(item.id,$event)"
      :style="'background-image: url('+item.path+')'"
    ><div class="item"  ></div>

    <div class="del" @click="funcs.deletePhoto(item.id)">X</div>
    </div>

    </div>
  <div class="upload-btn"><input type="file" accept="image/*"  @change="funcs.uploadPhoto($event)">上传</div>
</template>

<script>

import {reactive} from 'vue'
import {onMounted} from 'vue'
import img1 from '../assets/1.jpg';
import img2 from '../assets/2.jpg';
import img3 from '../assets/3.jpg';
import img4 from '../assets/4.jpg';
export default{
    name:"UploadImage",
    setup(){

        let data =reactive({
            msg:"hell",
            photos:[
                {id:1,title:"",path:img1,sort:0},
                {id:2,title:"",path:img2,sort:0},
                {id:3,title:"",path:img3,sort:0},
                {id:4,title:"",path:img4,sort:0},
        {id:5,title:"",path:img1,sort:0},
        {id:6,title:"",path:img2,sort:0},
        {id:7,title:"",path:img3,sort:0},
        {id:8,title:"",path:img4,sort:0},
            ]

        })
        let funcs =reactive({       
            drag:function(e){
                e.target.classList.add("hover");
                e.dataTransfer.setData("text/plain",e.target.id)
                e.dataTransfer.dropEffect = "copy";//拖曳时鼠标图标
            },
            dragend:function(e){                
                e.target.classList.remove("hover")
            },
            dragover:function(id,e){
        document.getElementById(id).classList.add("hover")
                e.preventDefault();
            },
            dragleave:function(id){
        document.getElementById(id).classList.remove("hover")
            },
            drop:function(id,e){

                document.getElementById(id).classList.remove("hover")
                let dragId=e.dataTransfer.getData('text/plain');
        this.sort(id,dragId);

            },
      sort:function(targetId,sourceId) {
        let target,source;
        data.photos.forEach(function(item){
          if( item.id==targetId){
            target=item;

          }
          if( item.id==sourceId){
            source=item;
          }
        })
        //互换位置
        data.photos.forEach(function(item,index,arr){

          if( item.id==target.id){
            arr[index]=source;
          }
          if( item.id==source.id){
            arr[index]=target;
          }
          arr[index].sort=(index+1)*10;
        })

      },
      uploadPhoto:function (event) {
        let r = new FileReader();
        r.readAsDataURL(event.target.files[0])
        r.onload = function (e){

          data.photos.push({id:9,title:"",path:this.result,sort:data.photos.length*10})
          //上传至服务器代码...
        }
      },
      deletePhoto:function (id) {
        data.photos.forEach(function(item,index,arr){
          if( item.id===id){
            data.photos.splice(index,1)

          }
        })
      }
        })

        onMounted(()=>{         

        })
        return{
            data,funcs,
        }

    }

}   
</script>

<style>
    .upload-wrapper{display: flex;flex-wrap:wrap;padding: 0.5%;}
    .upload-wrapper .item-wrapper{width: 24%; background-color: bisque;margin: 0.5%; position: relative;background-repeat: no-repeat;background-position: 50% 50%;}
  .upload-wrapper .item-wrapper,.landscape{background-size: 100% auto;}
  .upload-wrapper .item-wrapper .del{position: absolute; right: 0; top: 0; width: 20px; height: 20px; background-color: black;color: #fff;line-height: 20px;cursor: pointer}
  .upload-wrapper .item-wrapper .item{padding: 100% 50% 0% 0%;}
    .upload-wrapper .hover{opacity: 0.3;}

  .upload-btn{overflow: hidden;background-color: #42b983;position: relative; height: 100px;}
  .upload-btn input{opacity: 0.01;width: 100%; height: 100%;position: absolute;}
</style>