使用
<dragUpload :accept="accept" style="width:100%" @file="uploadFile" />
<template>
<div tabindex="0" :class="['drag', { 'drag-active': active }]" ref="upload">
<el-icon size="52" color="#2260FF">
<UploadFilled />
</el-icon>
<p class="drag-subtile">
支持点击/粘贴/拖拽到此区域上传,支持选择多个文件/文件夹
<br />
单个文件夹最大支持10M
</p>
<input ref="fileIpt" class="filePaste-ipt" />
<input class="file-ipt" type="file" :accept="accept" multiple @change="changeFile" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
const upload = ref(null)
const active = ref(false)
const fileIpt = ref(null)
defineProps(['accept'])
const handleMouseover = function (event) {
fileIpt.value.focus()
// 粘贴
fileIpt.value.addEventListener('paste', handlePaste)
}
const handleMouseout = function (event) {
fileIpt.value.blur()
fileIpt.value.removeEventListener('paste', handlePaste)
}
onMounted(() => {
// 拖拽
upload.value.addEventListener('drop', handleDrop)
upload.value.addEventListener('dragleave', handleDragleave)
upload.value.addEventListener('dragenter', handleDragenter)
upload.value.addEventListener('dragover', handleDragenter)
upload.value.addEventListener('mouseover', handleMouseover);
upload.value.addEventListener('mouseout', handleMouseout);
})
onUnmounted(() => {
upload.value.removeEventListener('drop', handleDrop)
upload.value.removeEventListener('dragleave', handleDragleave)
upload.value.removeEventListener('dragenter', handleDragenter)
upload.value.removeEventListener('dragover', handleDragenter)
upload.value.removeEventListener('mouseover', handleMouseover);
upload.value.removeEventListener('mouseout', handleMouseout);
})
const emit = defineEmits(["file"])
const handleFileName = (fileList) => {
let files = Array.from(fileList)
let renameReportFile = []
for (let i in files) {
renameReportFile.push(new File([files[i]], new Date().getTime() + files[i].name, { type: files[0].type }))
}
emit("file", renameReportFile)
}
const changeFile = (e) => {
e.preventDefault()
handleFileName(e.target.files)
}
const handleDragleave = (e) => {
active.value = false
e.preventDefault()
}
const handleDragenter = (e) => {
active.value = true
e.preventDefault()
}
const handleDrop = (e) => {
e.preventDefault()
active.value = false
handleFileName(e.dataTransfer.files)
}
const handlePaste = (e) => {
e.preventDefault()
handleFileName(e.clipboardData.files)
}
</script>
<style lang="scss" scoped>
@mixin borderColor($color: #2260FF) {
border: 1px dashed $color;
}
.drag {
position: relative;
height: 160px;
@include borderColor(#DEDEDE);
border-radius: 4px;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
&:active {
@include borderColor
}
&:hover {
@include borderColor
}
&-active {
@include borderColor
}
&-title {
font-size: 14px;
}
&-subtile {
width: 450px;
font-size: 12px;
color: #999999;
margin-top: 0;
text-align: center;
}
}
.file-ipt {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.filePaste-ipt {
position: fixed;
right: -100vw;
opacity: 0;
}
</style>