作者用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>