JS input type=file 上传文件夹

288 阅读1分钟

目的

需要上传一个文件夹,用到了input type=file 关键是 webkitdirectory 这个属性

方法

<div class="xxx" @click="handleClickInput">
    <el-button type="primary">上传文件</el-button>
    <input ref="inputRef" type="file" @change="selectFolder" @click.stop webkitdirectory />
</div>

@click.stop 这个很关键,目的是解决点击事件冒泡触发两次的问题

下面是方法

const handleClickInput = () => {
    if (inputRef.value) {
        inputRef.value.value = '';
        inputRef.value.click();
    }
}

inputRef.value.value = ''; 这行代码很关键,目的是解决二次上传失效的问题

上传

const selectFolder = (event: Event) => {
    //文件夹里面所有文件      
    const files = (event.target as HTMLInputElement).files;
    console.log('files', files);
    if (!files) {
        ElMessage.error('请选择文件夹');
        return;
    }
    // 文件夹名称        
    var relativePath = files[0].webkitRelativePath;
    var folderName = relativePath.split("/")[0];
    
    var formData = new FormData();
    
    // 文件信息转换成FormData结构遍历上传        
    for (var i = 0; i < files.length; i++) {
        formData.append('files', files[i]);
    }
    // 上传            
    uploadFiles(formData);
};

上传方法

async function uploadFiles(formData: FormData) {
    // for (var [a, b] of formData.entries()) {
    //     console.log(a, b);
    // } 
    const httpService = axios.create({
        timeout: 30000, // 超时时间3s
        headers: {
            // Axios 默认发送 JSON 数据,设置 headers 将 Content-Type 设置为 multipart/form-data 后,
            // 就会处理为 FormData 对象提交。
            'Content-Type': 'multipart/form-data'
        },
    });
    const url = ``;
    const response = await httpService.post(url, formData).then(res => res.data).catch(() => false);
    return response;
}