vue3 文件上传支持点击/粘贴/拖拽

 

使用

<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>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值