如何实现文件上、传拖拽功能

如何使用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. refsinput框实现了绑定,使用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 = ''
    }
  }
}

其实总结来说,拖拽上传本质和点击上传文件类似,不过这里我们在实现拖拽上传的时候,需要用到拖拽事件;当我们拖拽文件到浏览器的时候难免会触发浏览器自带的默认事件,我们这个时候就要去处理默认事件;之后我们在拖拽事件中获取事件对象中存着的我们需要上传的文件;之后发送请求给后台就可以了。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值