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