每当浏览一些网站时,总是能看到一些上传网站会使用图片上传的功能,而大部分的网站都支持图片的拖拽上传功能,这可以说是一个基本操作了,想想很多ui组件库也都包含了这个功能,但是,我们还是想要去试试,怎么自己写一个小demo,了解内部发生的事情,以便更好的使用组件
思路
- 使用input框的文件上传功能
- 拖拽区域
- 文件拖拽事件
- 获取文件内容,并上传
代码开始
第一步使用input框
文件上传功能都是依靠input框的上传,所以,我们需要准备一个容器,并且将input框包含在里面
<div
class="drag-area"
ref="dragArea"
>
<input class="file-input" type="file" />
<img class="preview" v-if="fileUrl" :src="fileUrl" alt="" />
</div>
第二步,设置可拖入区域
同时设置样式,让input框占满全部容器,并隐藏
.drag-area {
margin: 20px auto;
width: 150px;
height: 150px;
border-radius: 5px;
background-color: #eee;
position: relative;
}
.file-input {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
第三步 文件拖拽事件
使用文件拖拽,我们能想到的就是拖拽api,但是拖拽api这么多,我们用哪个呢 看看官方文档拖拽api
拖拽移入事件
- dragenter 当拖拽元素或选中的文本到一个可释放目标时触发
- dragover 当元素或选中的文本被拖到一个可释放目标上时触发(每 100 毫秒触发一次
- dragstart 当用户开始拖拽一个元素或选中的文本时触发
拖拽完成事件
- drop 当元素或选中的文本在可释放目标上被释放时触发
拖拽移出事件
- dragleave 当拖拽元素或选中的文本离开一个可释放目标时触发
要处理拖拽上传功能,重点在于drop api的实现
const handleDrop = (event) => {
const files = event.dataTransfer.files
const file = files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (e) => {
fileUrl.value = e.target.result
}
}
drop事件中,会获取到拖拽事件源,从事件源中,可以拿到拖拽上传的文件对象,而拿到文件对象后,可以让我们自己对文件进行处理,判断。
拖拽文件移入区域处理
在文件拖拽移入时,我们可以对拖拽区域设置一些样式
const handleDragEnter = (event) => {
dragArea.value.classList.add('drag-area-active')
}
拖拽文件移出区域移除样式
const handleDragLeave = (event) => {
dragArea.value.classList.remove('drag-area-active')
}
完整代码
<template>
<div>
<div
class="drag-area"
ref="dragArea"
@dragleave="handleDragLeave"
@drop="handleDrop"
@dragenter="handleDragEnter"
>
<input class="file-input" type="file" />
<img class="preview" v-if="fileUrl" :src="fileUrl" alt="" />
</div>
</div>
</template>
<script setup lang="ts">
const dragArea = ref(null)
const fileUrl = ref('')
const handleDragLeave = (event: any) => {
console.log('handleDragLeave', event)
dragArea.value.classList.remove('drag-area-active')
}
const handleDragEnter = (event: any) => {
console.log('handleDragEnter', event)
dragArea.value.classList.add('drag-area-active')
}
const handleDrop = (event: any) => {
dragArea.value.classList.remove('drag-area-active')
const files = event.dataTransfer.files
const file = files[0]
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (e) => {
fileUrl.value = e.target.result
}
}
</script>
<style scoped lang="less">
.drag-area {
margin: 20px auto;
width: 150px;
height: 150px;
border-radius: 5px;
background-color: #eee;
position: relative;
}
.drag-area-active {
background-color: #d9d9d9;
outline: 2px dashed #409eff;
padding: 10px;
}
.preview {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.file-input {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
</style>
结尾
文件拖拽上传的功能并不复杂,对于公司业务而言,还是使用ui组件库更完善一些,当然,有了文件拖拽上传的理解,也可以自己新增更多内容,自己实现一次,也可以更好的了解拖拽api的使用,同时,也是为了自己的学习过程。
最后,希望这些简单代码能够给你带来一些帮助,有问题的地方,可以指点出来,同时得到各位看官的谅解