需求
1,通过promise封装
2,文件类型和大小校验不通过时reject报错信息
3,可以多选文件
上代码
js版
/**
* @param fileTypeList 文件后缀列表,如['.png','.jpg']
* @param selectNum 选择数量 1和0为单选 其余多选
* @param size 文件大小限制 5m的话为 5*1025*1024
* @returns
*/
export const openChoiceFile = (fileTypeList, selectNum, size) => {
return new Promise((resolve, reject) => {
let input = document.createElement('input');
input.type = 'file';
input.accept = fileTypeList.join(',');
//判断是否多选
input.multiple = !(!selectNum || selectNum === 1);
input.onchange = (e) => {
const fileListObj = e.target.files;
//校验选择文件数量
if (fileListObj.length > selectNum) {
reject(`只能上传${selectNum}份文件`);
// 释放dom,避免内存泄漏
return (input = undefined);
}
const fileList = [];
//循环FileLists实例,FileLists不是数组只能用普通for循环
for (let i = 0; i < fileListObj.length; i++) {
const file = fileListObj.item(i);
//如果size有传,校验文件大小
if (size && file.size > size) {
reject(new Error(`文件过大,不可超过${(size / 1048576).toFixed(2)}M`));
// 释放dom,避免内存泄漏
return (input = undefined);
}
//校验文件类型
const fileType = file.name.slice(file.name.lastIndexOf('.'));
if (!fileTypeList.includes(fileType)) {
reject(new Error('文件类型错误'));
// 释放dom,避免内存泄漏
return (input = undefined);
}
fileList.push(file);
}
// 输出文件列表
resolve(fileList);
input = undefined; // 释放dom,避免内存泄漏
};
input.click();
});
};
ts版
/**
* @param fileTypeList 文件后缀列表,如['.png','.jpg']
* @param selectNum 选择数量 1和0为单选 其余多选
* @param size 文件大小限制 5m的话为 5*1025*1024
* @returns
*/
export const openChoiceFile = (
fileTypeList: string[],
selectNum: number,
size?: number
) => {
return new Promise<File[]>((resolve, reject) => {
let input: HTMLInputElement | undefined = document.createElement('input');
input.type = 'file';
input.accept = fileTypeList.join(',');
//判断是否多选
input.multiple = !(!selectNum || selectNum === 1);
input.onchange = (e: any) => {
const fileListObj = e.target.files;
//校验选择文件数量
if (fileListObj.length > selectNum) {
reject(`只能上传${selectNum}份文件`);
// 释放dom,避免内存泄漏
return (input = undefined);
}
const fileList: File[] = [];
//循环FileLists实例,FileLists不是数组只能用普通for循环
for (let i = 0; i < fileListObj.length; i++) {
const file = fileListObj.item(i);
//如果size有传,校验文件大小
if (size && file.size > size) {
reject(new Error(`文件过大,不可超过${(size / 1048576).toFixed(2)}M`));
// 释放dom,避免内存泄漏
return (input = undefined);
}
//校验文件类型
const fileType = file.name.slice(file.name.lastIndexOf('.'));
if (!fileTypeList.includes(fileType)) {
reject(new Error('文件类型错误'));
// 释放dom,避免内存泄漏
return (input = undefined);
}
fileList.push(file);
}
// 输出文件列表
resolve(fileList);
input = undefined; // 释放dom,避免内存泄漏
};
input.click();
});
};
使用方式:
//选择单个文件
const selectOne = async () => {
try {
//解构出单个文件
const [file] = await openChoiceFile(['.jpg', '.png'], 1, 5 * 1024 * 1024);
//打印单个文件
console.log(file);
} catch (err) {
//获取校验失败信息,提示用户
console.log(err);
}
};
//选择多个文件
const selectFive = async () => {
try {
const fileList = await openChoiceFile(['.jpg', '.png'], 5, 5 * 1024 * 1024);
//打印文件列表
console.log(fileList);
} catch (err) {
//获取校验失败信息,提示用户
console.log(err);
}
};