文件验证
Dropup 提供全面的文件验证,确保只接受有效的文件。
验证选项
Accept(文件类型)
指定要接受的文件类型:
// 仅接受图片
useDropup({ accept: 'image/*' });
// 接受特定类型
useDropup({ accept: 'image/png, image/jpeg' });
// 按扩展名接受
useDropup({ accept: '.pdf, .doc, .docx' });
// 多个类别
useDropup({ accept: ['image/*', 'application/pdf', '.txt'] });
常见的 Accept 模式
| 模式 | 描述 |
|---|---|
image/* | 所有图片 |
image/png, image/jpeg | 仅 PNG 和 JPEG |
video/* | 所有视频 |
audio/* | 所有音频文件 |
application/pdf | 仅 PDF 文件 |
.doc, .docx | Word 文档 |
*/* | 所有文件(默认) |
文件大小限制
useDropup({
maxSize: 10 * 1024 * 1024, // 最大 10MB
minSize: 1024, // 最小 1KB
});
文件数量限制
useDropup({
maxFiles: 5, // 最多 5 个文件
});
图片尺寸限制
useDropup({
accept: 'image/*',
maxWidth: 4096, // 最大宽度(像素)
maxHeight: 4096, // 最大高度(像素)
minWidth: 100, // 最小宽度(像素)
minHeight: 100, // 最小高度(像素)
});
自定义验证规则
创建自定义验证逻辑:
useDropup({
customRules: [
// 规则 1:检查文件名长度
(file) => {
if (file.name.length > 100) {
return '文件名必须少于 100 个字符';
}
return true;
},
// 规则 2:检查特定内容
(file) => {
if (file.name.includes('draft')) {
return '不允许草稿文件';
}
return true;
},
// 规则 3:异步验证
async (file) => {
const hash = await calculateHash(file);
const exists = await checkDuplicate(hash);
if (exists) {
return '此文件已上传';
}
return true;
},
],
});
规则返回值
| 返回值 | 含义 |
|---|---|
true | 验证通过 |
false | 验证失败(通用错误) |
string | 验证失败并带有自定义消息 |
处理验证错误
使用 onValidationError 回调:
useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors: fileErrors }) => {
console.log(`${file.name} 验证失败:`);
fileErrors.forEach(error => console.log(` - ${error}`));
});
// 显示用户友好的消息
toast.error(`${errors.length} 个文件验证失败`);
},
});
验证错误结构
interface ValidationError {
file: File; // 失败的文件
errors: string[]; // 错误消息数组
}
预构建的验证规则
Dropup 包含常见的验证规则:
import { commonRules } from '@samithahansaka/dropup';
useDropup({
customRules: [
commonRules.noExecutables, // 阻止 .exe、.bat 等
commonRules.noHiddenFiles, // 阻止以 . 开头的文件
commonRules.maxFilenameLength(50),
commonRules.allowedExtensions(['.jpg', '.png', '.pdf']),
],
});
拖拽验证反馈
在拖拽过程中提供视觉反馈:
function DropZone() {
const { getDropProps, state } = useDropup({
accept: 'image/*',
});
// state.isDragAccept - 文件符合接受标准
// state.isDragReject - 文件不符合
return (
<div
{...getDropProps()}
style={{
borderColor: state.isDragAccept
? 'green'
: state.isDragReject
? 'red'
: 'gray',
}}
>
{state.isDragReject && <p>不接受此文件类型!</p>}
</div>
);
}
完整验证示例
import { useDropup, commonRules } from '@samithahansaka/dropup';
function SecureUploader() {
const { files, state, getDropProps, getInputProps } = useDropup({
// 文件类型
accept: ['image/jpeg', 'image/png', 'application/pdf'],
// 大小限制
maxSize: 10 * 1024 * 1024, // 10MB
minSize: 100, // 100 字节(防止空文件)
// 数量限制
maxFiles: 10,
// 图片尺寸(仅适用于图片)
maxWidth: 8000,
maxHeight: 8000,
// 自定义规则
customRules: [
commonRules.noExecutables,
commonRules.maxFilenameLength(100),
// 自定义:不允许文件名包含空格
(file) => {
if (file.name.includes(' ')) {
return '文件名不能包含空格';
}
return true;
},
],
// 错误处理
onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
alert(`${file.name}:${errors.join(',')}`);
});
},
});
return (
<div
{...getDropProps()}
className={`dropzone ${
state.isDragReject ? 'reject' : state.isDragAccept ? 'accept' : ''
}`}
>
<input {...getInputProps()} />
{state.isDragReject ? (
<p>❌ 某些文件将被拒绝</p>
) : (
<p>📁 将文件拖放到此处(仅限 JPEG、PNG、PDF,最大 10MB)</p>
)}
</div>
);
}