获取文件/文件结构(封装集合)
获取文件示例
vue
<template>
<input type="file" ref="InputDom" accept="image/jpeg, image/png, image/gif, image/jpg, image/gif, image/webp" @change="monitorFile($event)" style="display: none;">
</template>
<script>
import { ref } from 'vue';
// 获取dom元素
const InputDom = ref<HTMLInputElement>();
// 选择文件后接收文件
const monitorFile = (e: Event) => {
const el = e.target as HTMLInputElement;
console.log(el.files);
}
</script>注意事项
如果是拖动某一些文件到特定区域,如:文件上传,拖动文件到div上;
一定要阻止【默认行为】,要不然浏览器会跳转新窗口打开文件;
拖动到div的文件,使用事件对象获取,从 dataTransfer 中获取文件列表【e.dataTransfer.files】
ts
@dragover.prevent 和 @drop.prevent="monitorFile($event)" // 重要input选择文件属性
TIP
1.选择多个文件【不写就是默认选择一个】:
multiple="true" 属性 【或】 multiple="multiple" 属性 ==> 开启选择多个文件
vue
<input type="file" multiple="true"/>
<!-- 或 -->
<input type="file" multiple="multiple"/>2.选择文件夹: webkitdirectory mozddirectory oddirectory 兼容属性(个必填)只能选择文件夹
vue
<input type="file" multiple="true" webkitdirectory mozddirectory oddirectory/>限制选择文件属性accept
一. 【使用 MIME 类型(推荐)】:
1). 所有图片:
accept="image/*";特定图片格式:accept="image/jpeg, image/png, image/gif"2). 所有视频:
accept="video/*"特定视频格式:accept="video/mp4, video/webm"3). 所有音频:
accept="audio/*";4). PDF 文档:
accept="application/pdf";二. 【使用文件扩展名】:
1). 限制特定后缀:
accept=".jpg, .png, .pdf"2). 混合使用:
accept=".doc, .docx, application/pdf"三. 【混合使用】
1).
accept="image/*, .pdf, application/msword"(接受所有图片、PDF文件以及旧版Word文档)
获取移动到元素上的的方法
ts
<html元素>.ondragstart => (e.preventDefault()) // 开始拖动元素时触发
<html元素>.ondrag => (e.preventDefault()) // 拖动过程中持续触发
<html元素>.ondragend => (e.preventDefault()) // 拖动结束时触发(无论成功失败)
<html元素>.ondragenter => (e.preventDefault()) // 文件移进后触发
<html元素>.ondragover => (e.preventDefault()) // 文件移动触发
<html元素>.ondragleave => (e.preventDefault()) // 离开目标元素时触发【离开移动区域】
<html元素>.ondrop => (e.preventDefault()) // 文件放下后触发获取数据结构
ts
// 获取数据结构 (移动到div上)
export const getFiles = (res) => {
return new Promise(async (response) => {
response(await getFile(res));
async function getFile(entry: any) {
// console.log(entry.name);
if (entry.name === "node_modules" || entry.name === "miniprogram_npm")
return {
// 文件
type: "files",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: 'files',
// 文件名
name: entry.name,
// 种类, 性质, 方式
fullPath: entry.fullPath,
// file文件
file: [],
};
if (entry.isFile) {
// 表示是一个文件
return {
// 文件
type: "file",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: entry.name.split(".").pop().toLocaleLowerCase(),
// 文件名
name: entry.name,
// 种类, 性质, 方式
fullPath: entry.fullPath,
// file文件
file: await callhander(entry),
};
} else {
// 表示是一个文件夹列表
let files: any = await hander(entry);
return {
// file文件
files,
// 文件
type: "files",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: 'files',
// 文件名
name: entry.name,
// 种类, 性质, 方式
fullPath: entry.fullPath,
// 提示信息
msg: files.length ? "many file" : `“${entry.name}”为空`,
};
}
}
// 创建异步迭代器
function hander(entry) {
return new Promise((res) => {
let arr = [];
// 表示是一个文件夹列表
const reader = entry.createReader();
reader.readEntries(async (en) => {
if (!en.length) res(arr);
for (const el of en) {
arr.push(await getFile(el));
if (arr.length == en.length) {
res(arr);
}
}
});
});
}
});
// item为遍历每一项的FileEntry对象,调用 原型上的 file 方法使其转换为file对象 通过回调函数的方法返给调用者
function callhander(item: any) {
return new Promise((res) => {
// 把转换的结构暴露出
item.file((r: any): void => res(r));
});
}
}点击上传按钮 (提取所有文件)
ts
// 点击上传按钮(提取所有文件)
export const getHander = (target: any) => {
return new Promise(response => {
response({
// 文件名称
name: target[0].webkitRelativePath.split("/")[0],
// 默认是否打开
isFLag: false,
// 提示信息
msg: "many file",
// 文件类型
type: "files",
// 图标类型
typeName: "files",
// 文件集合
files: [...target].reduce((val, item) => {
return [
...val,
{
// 文件名称
name: item.name,
// 默认是否打开
isFLag: false,
// 提示信息
msg: "ok",
// 文件类型
type: "file",
// 图标类型
typeName: item.name.split(".").pop(),
// file文件
file: item,
},
];
}, []),
})
});
}读取器读取的文件目录
ts
// 打开文件内容
let res: any = await window.showDirectoryPicker();
// 获取文件内容
const root: any = await getFolder(res);
console.log(root);
// 获取文件结构
function getFolder(res) {
return new Promise((response) => {
response(fn(res));
async function fn(handle: any) {
if (handle.kind === "file") {
return {
// 文件
type: "file",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: handle.name.split(".").pop().toLocaleLowerCase(),
// 文件名
name: handle.name,
// 句柄
handle,
// 种类, 性质, 方式
kind: handle.kind,
};
}
// 添加判断node_modules模块,直接返回该模块文件夹
if (handle.name === "node_modules" || handle.name === "miniprogram_npm") {
return {
// 文件
type: "files",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: "files",
// 文件名
name: handle.name,
// 种类, 性质, 方式
kind: handle.kind,
// 文件列表
files: handle.files,
// 句柄
handle,
};
}
handle.files = [];
// 得到异步迭代器
const inter = handle.entries();
for await (const item of inter) {
handle.files.push(await getFolder(item[1]));
}
return {
// 文件
type: "files",
// 开关节流阀
isFLag: false,
// 后缀名
typeName: "files",
// 文件名
name: handle.name,
// 种类, 性质, 方式
kind: handle.kind,
// 文件列表
files: handle.files,
// 句柄
handle,
};
}
});
}创建读取器
ts
// 创建读取对象
const reader = new FileReader();
// 音频读取
reader.readAsDataURL('音频file文件');
reader.onload = (e) => {
console.log({
status: 200,
msg: `读取成功`,
type: "img",
data: {
src: e.target.result,
},
})
};
// 读取文本
// 文本自动读取
reader.readAsText('文件发file文件', "UTF-8");
reader.onload = (e) => {
// 默认配置
console.log({
status: 200,
msg: `读取成功`,
type "text",
data: {
e.target.result
},
})
};