Vue:纯前端实现文件拖拽上传

先看一下拖拽相关的事件:dragoverdragenter dropdragleave

  • dragover事件:当被拖动的元素在一个可放置目标上方时,该事件会被触发。

    通常,我们会使用event.preventDefault()方法来取消浏览器默认的拖放行为,以便可以自定义拖拽行为。这个事件在拖拽过程中会持续触发,可以用于实现一些特殊的样式效果,如显示拖拽目标的悬浮效果。

  • drop事件:当拖动的元素被释放时,该事件会被触发。

    drop事件中,可以获取拖放的数据,并进行相应的处理。通过event.dataTransfer对象可以获得拖放相关的数据,包括被拖动的文件列表或其他自定义数据。我们可以在drop事件的处理函数中执行文件上传、移动元素等操作。
    注意,drop和dragover必须一起使用,不然drop无法被触发

  • dragenter事件:当被拖动的元素进入一个可放置目标时,该事件会被触发。

    这个事件通常与dragover事件一起使用,用于改变可放置目标的样式或状态,以向用户展示目标元素的拖放状态。

  • dragleave事件:当被拖动的元素离开一个可放置目标时,该事件会被触发。

    dragenter事件相似,这个事件也常常和dragover事件一起使用,用于恢复目标元素的样式或状态,以向用户展示拖放状态的变化。

具体实现:

javascript 复制代码
<template>
  <div
    class="content"
    :class="{ 'drag-enter': dragEnter }"
    @dragover="handleDragOver"
    @dragenter="handleDragEnter"
    @dragleave="handleDragLeave"
    @drop="handleFileDrop"
  >
    <div v-if="!fileContent">将文件拖拽到这里显示</div>
    <p v-else>{{ fileContent }}</p>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const dragEnter = ref(false);
const fileContent = ref("");

// 被拖动的元素进入可放置目标时
const handleDragEnter = (e: DragEvent) => {
  dragEnter.value = true;
  e.preventDefault();
};

// 被拖动的元素在可放置目标上方时
const handleDragOver = (e: DragEvent) => {
  dragEnter.value = true;
  e.preventDefault();
};

// 被拖动的元素离开可放置目标时
const handleDragLeave = (e: DragEvent) => {
  dragEnter.value = false;
  e.preventDefault();
};

// 释放被拖动的元素
const handleFileDrop = (e: DragEvent) => {
  dragEnter.value = false;
  e.preventDefault();
  // 获取上传的文件,files是一个数组,可能同时存在一次拖拽多个文件的情况
  const files = e.dataTransfer?.files as FileList;
  // 此处只处理第一个上传的文件,file包含了上传的文件大小、类型、名称等信息
  const file = files[0];
  //  限制文件大小
  if (file.size / 1024 / 1024 > 10) {
    console.log("文件不能大于10M。");
    return;
  }
  // 限制文件类型
  if (!["text/plain", "application/json"].includes(file.type)) {
    console.log("仅支持txt、 json文件。");
    return;
  }
  // 定义一个文件读取器,读取文件内容
  let reader = new FileReader();
  reader.readAsText(file, "UTF-8");
  reader.onload = (e: ProgressEvent<FileReader>) => {
    fileContent.value = e.target?.result;
  };
};
</script>

<style scoped>
.content {
  width: 400px;
  height: 400px;
  overflow: auto;
  border: 1px solid #dcdfe6;
}
.empty-tips {
  margin: 0 auto;
}
.drag-enter {
  border: 1px solid #45a3ff;
}
</style>

页面展示:

实现其实很简单,主要就是掌握拖拽相关的几个事件。

相关推荐
懒大王95271 小时前
echarts+HTML 绘制3d地图,加载散点+散点点击事件
前端·html·echarts
陈皮话梅糖@3 小时前
使用 Provider 和 GetX 实现 Flutter 局部刷新的几个示例
开发语言·javascript·flutter
Yolo@~7 小时前
个人网站:基于html、css、js网页开发界面
javascript·css·html
斯~内克7 小时前
Electron 菜单系统深度解析:从基础到高级实践
前端·javascript·electron
数据知道7 小时前
【YAML】一文掌握 YAML 的详细用法(YAML 备忘速查)
前端·yaml
清风絮柳7 小时前
51. “闲转易”交易平台小程序(基于springboot&vue)
vue.js·spring boot·小程序·毕业设计·校园二手交易平台·二手交易小程序·闲转易交易系统
dr李四维7 小时前
vue生命周期、钩子以及跨域问题简介
前端·javascript·vue.js·websocket·跨域问题·vue生命周期·钩子函数
旭久7 小时前
react+antd中做一个外部按钮新增 表格内部本地新增一条数据并且支持编辑删除(无难度上手)
前端·javascript·react.js
windyrain7 小时前
ant design pro 模版简化工具
前端·react.js·ant design
浪遏7 小时前
我的远程实习(六) | 一个demo讲清Auth.js国外平台登录鉴权👈|nextjs
前端·面试·next.js