浏览器上传文件夹的两种实现方式(demo)

本文介绍如何使用Vue实现文件夹的拖拽上传和选择上传功能,包括通过监听拖拽事件和利用<input>标签实现文件夹选择,以及递归遍历文件夹树结构进行文件上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理

注意:有浏览器版本限制

实现文件夹上传有两种:一种是通过将文件夹拖拽到浏览器,实现上传;另一种是通过 <input> 标签,用户选择文件夹实现上传

使用 vue 开发时,需要添加 @dragover="e=>e.preventDefault()"。否则拖拽文件夹不会触发 @drop,只会触发浏览器默认行为

示例代码

<template>
  <div id="app">
    <div id="p"></div>
    <img alt="Vue logo" src="./assets/logo.png">
    <div>
      <label for="folder">
        Choose folder or files to upload:
        <input id="folder" type="file" webkitdirectory mozdirectory @change="handleInputChanged">
      </label>
    </div>

    <div id="drop" @dragover="e=>e.preventDefault()"
                   @drop="handleDropEvent">
      Drop folder for files to upload
    </div>
  </div>
</template>

<script>

const traverseFileTree = function self(item, p) {
  const path = p || '';
  if (item.isFile) {
    // Get file
    item.file((file) => {
      console.log('file:', file, path);
      const form = new FormData();
      form.append('file', file);
      form.append('dir', path);
      form.append('name', file.name);

      // TODO: upload file
    });
  } else if (item.isDirectory) {
    // Get folder contents
    const dirReader = item.createReader();
    dirReader.readEntries((entries) => {
      for (let i = 0; i < entries.length; i += 1) {
        self(entries[i], `${path}${item.name}/`);
      }
    });
  }
};

export default {
  name: 'App',
  methods: {
    handleInputChanged(evt) {
      if (!evt || !evt.target) return;
      const { files: fileList } = evt.target;
      console.log('this:', this);
      for (let i = 0; i < fileList.length; i += 1) {
        const file = fileList[i];
        const form = new FormData();
        form.append('file', file);
        form.append('path', file.webkitRelativePath);
        form.append('name', file.name);

        // TODO: upload file
      }
    },

    handleDropEvent(evt) {
      evt.stopPropagation();
      evt.preventDefault();
      const { length } = evt.dataTransfer.items;
      for (let i = 0; i < length; i += 1) {
        // recursive directory search
        traverseFileTree(evt.dataTransfer.items[i].webkitGetAsEntry());
      }
      return false;
    },
  },
};
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

#drop {
  height: 200px;
  line-height: 200px;
  margin-top: 20px;
  background-color: aqua;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值