前言
最近有项目需要开发一个批量上传图片到服务器并做数据回显的功能,前端实现用到React+Antd,记录一下基本的设计思路。
一、Upload组件解析
action: 文件上传的接口地址。
fileList: 已经上传的文件列表(受控)。
beforeUpload: 上传文件之前的钩子,参数为上传的文件,若返回
false
则停止上传。onChange:上传文件改变时的状态。
onPreview: 点击文件链接或预览图标时的回调。
二、实现过程
1.基本思路
将upload封装成一个独立的组件,在需要的地方引入,在父组件向接口拉取fileList传递给upload组件。
2.代码实现
封装upload组件
import React, { Component } from 'react'
import {Upload, Icon} from 'antd'
import PictureUpload from './upload'
export class PictureUploads extends Component {
constructor() {
super();
}
//图片上传的回调
handleUploadChange = (info) => {
const {updateParentFileList} = this.props; //在父组件定义setstate方法
if (info.file.status === 'uploading') {
//正在上传处理逻辑
}
if (info.file.status === 'done') {
//上传成功处理逻辑
} else if (info.file.status === 'error') {
//上传失败处理逻辑
}
//对于受控模式,应该在onChange中始终setState fileList 保证所有状态同步到Upload内
//不然会出现onChange方法只会执行一次,且info.file.status一直为uploading的情况
// this.setState({fileList: info.fileList});
updateParentFileList(info.fileList); //在父组件setstate
};
//限制上传内容
handleBeforeUpload = file => {
//限制图片 格式、size
const isJPG = file.type === 'image/jpeg';
const isJPEG = file.type === 'image/jpeg';
const isGIF = file.type === 'image/gif';
const isPNG = file.type === 'image/png';
if (!(isJPG || isJPEG || isGIF || isPNG)) {
return false;
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
return false;
}
return (isJPG || isJPEG || isGIF || isPNG) && isLt2M;
};
//图片预览逻辑
handlePreview = async file => {
//实现点击显示大图逻辑
};
//点击移除图片的回调
onRemove = (file) => {
//实现点击移除图片逻辑
};
render() {
const {fileList} = this.props;
const uploadButton = (
<div>
<Icon type="plus" />
<div className="ant-upload-text">Upload</div>
</div>
);
const props = {
name: 'files',
accept: 'image/jpg, image/png, image/jpeg', //接受上传的文件类型
action: '/api', //图片上传的接口地址
fileList: fileList, //已经上传的文件列表,父组件传递下来
headers: {
token: window.sessionStorage.getItem('token'),
},
beforeUpload: this.handleBeforeUpload,
listType: "picture-card",
multiple: true,
onRemove: this.onRemove,
data: {}, // 接口的请求参数
onPreview: this.handlePreview,
onChange: this.handleUploadChange
};
return (
<Upload {...props}>
{fileList.length >= 8 ? null : uploadButton}
</Upload>
)
}
}
export default PictureUploads
在需要的地方引入upload组件
import React, { Component } from 'react'
import PictureUploads from './Uploads'
export class Parent extends Component {
constructor() {
super();
this.updateParentFileList= this.updateParentFileList.bind(this);
this.state = {
//接口拉取的数据赋值给fileList
fileList: []
}
};
//修改state
updateParentFileList(fileList) {
//在这里就可以取到子组件传来的值
this.setState({
fileList: fileList
})
};
render() {
const {fileList} = this.state;
//传递给PictureUploads组件的参数
const pictureProps = {
fileList: fileList,
updateParentFileList: this.updateParentFileList,
}
return (
//在Form组件中使用Upload组件,然后提交将表单提交到服务器
<PictureUploads {...pictureProps}/>
)
}
}
export default Parent