如何使用js实现文件点击、拖拽上传功能
这里简易封装一个vue中点击和拖拽上传文件的功能,是一个文件上传的组件
以下是组件的结构,用到了element-ui的组件
// myFile.vue
<template>
<el-dialog
width="500px"
title="导入员工信息"
:visible="showExcelDialog"
@close="close"
>
<el-row type="flex" justify="center">
<div class="upload-excel">
<!-- 这里用的是原生 input框 原本的input框样式太丑 在这里设置样式覆盖原来的样式 -->
<!-- accept=".xlsx" 上传文件格式 -->
<input
ref="excel-upload-input"
class="excel-upload-input"
type="file"
accept=".xlsx"
@change="hChangefile"
>
<!-- 文件拖拽 ref="drop" draggable="true" drag 拖拽事件-->
<div class="drop" @dragover.prevent @dragenter.prevent @drop="handleDrop">
<i class="el-icon-upload" />
<!-- 这里有一个下载导入模板的功能 如果没有接口 是无法获取到模板 所以这个功能我这里没有写上去 -->
<el-button type="text">下载导入模板</el-button>
<span>将文件拖到此处或
<el-button type="text" @click="hUpload">点击上传</el-button>
</span>
</div>
</div>
</el-row>
<el-row type="flex" justify="end">
<!-- update:props属性名,值 直接修改 .sync修饰符的属性值 -->
<el-button size="mini" type="primary" @click="$emit('update:showExcelDialog', false)">取消</el-button>
</el-row>
</el-dialog>
</template>
<style scoped lang="scss">
.upload-excel {
display: flex;
justify-content: center;
margin: 20px;
width: 360px;
height: 180px;
align-items: center;
color: #697086;
.excel-upload-input {
display: none;
z-index: -9999;
}
.btn-upload,
.drop {
border: 1px dashed #dcdfe6;
width: 100%;
height: 100%;
text-align: center;
line-height: 160px;
border-radius: 8px;
display: flex;
flex-direction: column;
justify-content: center;
}
.drop {
line-height: 40px;
color: #bbb;
i {
font-size: 60px;
display: block;
color: #c0c4cc;
}
}
}
</style>
1-首先实现的是点击上传文件的功能
① 点击文件上传实际上用的是input框的是自带功能
② 这里我们用样式覆盖了原有的比较丑的input框并
③ 使用了vue中 ref 和 r e f s 对 i n p u t 框实现了绑定 , 使用 t h i s . refs 对input框实现了绑定,使用this. refs对input框实现了绑定,使用this.refs[‘excel-upload-input’].click()拿到input框并调用它的点击事件打开我们需要上传文件的弹框
④accept 是需要定义上传的文件类型 这里我们上传是excel 文件 所以以 .xlsx 结尾
⑤ input 框自带有一个change事件 该事件需要通过上传文件触发
<script>
// 导入 导出excel 文件的包
import FileSaver from 'file-saver'
import { getExportTemplate, upExcel } from '@/api/employee'
export default {
props: {
showExcelDialog: {
type: Boolean,
required: true
}
},
methods: {
// 关闭弹框 告诉父组件关闭
close() {
this.$emit('update:showExcelDialog', false)
},
hUpload() {
// 弹出文件选择框:模拟input type=file的click
// 原生input框有上传文件的功能 但是太丑了 用css样式隐藏起来了
// 使用ref绑定input框 通过点击事件调用其本身有的方法==即弹出上传文件的框
this.$refs['excel-upload-input'].click()
},
// 这个是点击上传事件 上传之后我们可以将 e 事件对象打印出来看一下
// 如下三图
async hChangefile(e) {
console.log(e)
// 事件对象e 中会自动收集当前用户选中的文件
const file = e.target.files[0]
console.log(file)
if (file) {
// 1 准备参数文件上传的参数--固定格式
// 上传 file文件的固定格式
const fd = new FormData()
fd.append('file', file)
// try 捕获事件 当我们提交第一次如果发现文件中的内容重复的时候, 再次提交就无法触发change事件,这个时候,就不会再次发送请求,原因是报错之后代码不会继续往后执行, 使用到 try 和 finally 不管有报错还是没有报错都会继续往下执行 当报错的时候 我们将 input框的value值设置为空 ,下一次上传的时候就能再次触发change事件
try {
// 2调用接口,做文件上传
await upExcel(fd)
this.$message.success('操作成功')
// 3通知父组件更新数据
// 3.1 通知父组件
this.$emit('updateEmployee')
// 3.2关闭弹框
this.$emit('update:showExcelDialog', false)
} finally {
this.$refs['excel-upload-input'].value = ''
}
}
},
// 拖拽上传的代码
}
}
}
</script>
2- 我们在文件实现拖拽功能时需要阻止浏览器的默认事件
@dragover.prevent 指令用于监听 dragover 事件,并调用 .prevent 修饰符来阻止浏览器默认的拖拽行为。默认情况下,浏览器不允许在元素上放置拖动的元素,通过使用 .prevent 修饰符,我们可以阻止浏览器默认行为并允许元素成为拖放目标。
@dragenter.prevent 指令用于监听 dragenter 事件,并调用 .prevent 修饰符来阻止浏览器默认的拖入行为。当拖拽元素进入可拖放的区域时,浏览器会默认显示一个“禁止”图标,通过使用 .prevent 修饰符,我们可以阻止浏览器默认行为并自定义处理。
这两个指令中的 .prevent 修饰符是Vue提供的一种简化写法,用于阻止默认事件的传播。它等价于在事件处理程序中使用 event.preventDefault() 来取消事件的默认行为。
通过在事件监听器中使用 .prevent 修饰符,我们可以阻止浏览器默认的拖拽行为,以便在Vue组件中自定义处理拖拽事件。
methods{
// 拖拽上传文件
async handleDrop(e) {
// 阻止浏览器的默认行为
e.preventDefault()
// console.log(e.dataTransfer.files[0])
const file = e.dataTransfer.files[0]
console.log(file)
if (file) {
// 1 准备参数文件上传的参数--固定格式
// 上传 file文件的固定格式
const fd = new FormData()
fd.append('file', file)
// try 捕获事件 当我们提交第一次如果发现文件中的内容重复的时候, 再次提交就无法触发change事件,这个时候,就不会再次发送请求,原因是报错之后代码不会继续往后执行, 使用到 try 和 finally 不管有报错还是没有报错都会继续往下执行 当报错的时候 我们将 input框的value值设置为空 ,下一次上传的时候就能再次触发change事件
try {
// 2调用接口,做文件上传
await upExcel(fd)
this.$message.success('操作成功')
// 3通知父组件更新数据
// 3.1 通知父组件
this.$emit('updateEmployee')
// 3.2关闭弹框
this.$emit('update:showExcelDialog', false)
} finally {
this.$refs['excel-upload-input'].value = ''
}
}
}
其实总结来说,拖拽上传本质和点击上传文件类似,不过这里我们在实现拖拽上传的时候,需要用到拖拽事件;当我们拖拽文件到浏览器的时候难免会触发浏览器自带的默认事件,我们这个时候就要去处理默认事件;之后我们在拖拽事件中获取事件对象中存着的我们需要上传的文件;之后发送请求给后台就可以了。