3种场景搞定umi文件上传:从基础表单到高级拖拽
【免费下载链接】umi A framework in react community ✨ 项目地址: https://gitcode.com/gh_mirrors/umi8/umi
你还在为umi项目中的文件上传功能头疼吗?无论是简单的表单上传、炫酷的拖拽上传,还是需要实时进度显示的大文件上传,本文都能帮你一网打尽。读完你将掌握:基础表单上传实现、拖拽上传组件开发、大文件分片上传方案,以及完整的错误处理机制。
基础表单上传实现
核心代码实现
在umi项目中实现基础文件上传,首先需要创建一个包含文件输入框的表单。在pages目录下新建UploadPage.js文件:
import { useState } from 'react';
import { Button, message } from 'antd';
export default () => {
const [fileList, setFileList] = useState([]);
const handleFileChange = (e) => {
const file = e.target.files[0];
if (!file) return;
setFileList([file]);
const formData = new FormData();
formData.append('file', file);
// 上传逻辑
fetch('/api/upload', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
message.success('上传成功');
})
.catch(error => {
message.error('上传失败');
});
};
return (
<div>
<input
type="file"
onChange={handleFileChange}
style={{ display: 'none' }}
id="fileInput"
/>
<Button onClick={() => document.getElementById('fileInput').click()}>
选择文件上传
</Button>
</div>
);
};
配置代理解决跨域
为避免跨域问题,需要在config/config.js中配置代理:
export default {
proxy: {
'/api': {
target: 'http://your-server.com',
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
},
};
详细配置说明可参考官方文档:config.md。
拖拽上传组件开发
拖拽区域实现
利用HTML5的拖放API,可以实现拖拽上传功能。创建components/DragUpload.js组件:
import { useState } from 'react';
import { Upload, message } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
const { Dragger } = Upload;
export default () => {
const [uploading, setUploading] = useState(false);
const props = {
name: 'file',
action: '/api/upload',
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 文件上传成功`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 文件上传失败`);
}
},
};
return (
<Dragger {...props}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">点击或拖拽文件到此处上传</p>
<p className="ant-upload-hint">
支持单个或批量上传,严禁上传公司敏感文件
</p>
</Dragger>
);
};
在页面中使用拖拽组件
在之前创建的UploadPage.js中引入拖拽组件:
import DragUpload from '../components/DragUpload';
export default () => {
return (
<div>
<h2>基础表单上传</h2>
{/* 之前的表单上传代码 */}
<h2>拖拽上传</h2>
<DragUpload />
</div>
);
};
大文件分片上传方案
分片上传核心逻辑
对于大文件,我们需要实现分片上传功能。创建utils/upload.js工具函数:
export const chunkUpload = async (file, chunkSize = 2 * 1024 * 1024) => {
const fileId = Date.now().toString();
const totalChunks = Math.ceil(file.size / chunkSize);
const uploadPromises = [];
for (let i = 0; i < totalChunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('fileId', fileId);
formData.append('chunkIndex', i);
formData.append('totalChunks', totalChunks);
formData.append('fileName', file.name);
uploadPromises.push(
fetch('/api/upload/chunk', {
method: 'POST',
body: formData,
}).then(res => res.json())
);
}
await Promise.all(uploadPromises);
// 通知服务器合并分片
return fetch('/api/upload/merge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileId, fileName: file.name }),
}).then(res => res.json());
};
进度显示实现
结合umi的request库和进度条组件,可以实现上传进度显示:
import { Upload, Progress } from 'antd';
import { chunkUpload } from '../utils/upload';
export default () => {
const [progress, setProgress] = useState(0);
const handleUpload = async (file) => {
await chunkUpload(file, (percent) => {
setProgress(percent);
});
return false;
};
return (
<div>
<Upload beforeUpload={handleUpload}>
<Button>大文件分片上传</Button>
</Upload>
{progress > 0 && <Progress percent={progress} />}
</div>
);
};
错误处理与最佳实践
完整错误处理机制
在实际项目中,需要处理各种可能的上传错误:
const handleUpload = async (file) => {
try {
setUploading(true);
await chunkUpload(file);
message.success('上传成功');
} catch (error) {
if (error.message.includes('网络错误')) {
message.error('网络异常,请检查网络连接');
} else if (error.message.includes('文件过大')) {
message.error('文件超过最大限制,请上传小于100MB的文件');
} else {
message.error('上传失败,请稍后重试');
}
} finally {
setUploading(false);
}
return false;
};
项目结构与文件组织
推荐的文件上传相关代码组织方式:
src/
├── components/
│ ├── DragUpload.js // 拖拽上传组件
│ └── FileUploader.js // 通用上传组件
├── pages/
│ └── UploadPage.js // 上传功能页面
└── utils/
└── upload.js // 上传工具函数
更多项目结构规范可参考官方文档:app-structure.md。
总结与扩展
本文介绍了umi项目中三种常见的文件上传场景:基础表单上传、拖拽上传和大文件分片上传。通过这些方案,你可以满足大多数项目的文件上传需求。在实际开发中,还可以根据需要扩展功能,如文件格式验证、上传速度限制、断点续传等。
如果你有更复杂的上传需求,可以考虑集成第三方上传服务,如阿里云OSS、腾讯云COS等,它们提供了更完善的上传解决方案和更可靠的存储服务。
希望本文对你有所帮助,如果你有任何问题或更好的解决方案,欢迎在评论区留言讨论。别忘了点赞、收藏本文,关注作者获取更多umi开发技巧!
下期预告:umi中实现文件预览功能,支持多种文件格式在线查看。
【免费下载链接】umi A framework in react community ✨ 项目地址: https://gitcode.com/gh_mirrors/umi8/umi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



