1.单个文件上传组件,无文件时显示上传,有文件时显示文件,可删除,重新上传,样式适合图片上传,可根据文件格式更改样式,效果图如下。
页面调用代码
<FormItem
{...formItemLayout}
label="头像"
>
{getFieldDecorator('headImg', {
initialValue: headImg,
})(
<UploadButton
imageUrl={headImg}
handleUpload={this.handleUpload}
handleDelete={this.handleDeleteImage}
/>
)}
</FormItem>
上传文件与删除文件方法
state = {
headImg: null,
};
handleDeleteImage = () => {
this.setState({
headImg: null,
});
};
handleUpload = (info) => {
if (info.file.status === 'done') {
if(info.file.response.statusCode === 1) {
this.setState({
headImg: info.file.response.data,
});
}
}
};
文件上传组件与样式
import React from 'react';
import { Icon, Divider, Tooltip, Upload } from 'antd';
import classnames from 'classnames';
import styles from './index.css';
import { apiUri, fileUri } from '@/constant';
export default class UploadButton extends React.PureComponent {
state = {
loading: false,
};
render() {
const { className, style, uploadText, imageUrl, handleUpload, handleDelete, action, filePath } = this.props;
const uploadUrl = action || `${apiUri}/upload/file`;
const filePri = filePath || fileUri;
return (
<>
{
imageUrl ?
<Tooltip
title={
<>
{
handleDelete ?
<>
<a onClick={handleDelete} style={{ color: '#FFF' }}>删除</a>
<Divider type="vertical" style={{ width: '2px' }} />
</>
: null
}
<Upload
showUploadList={false}
action={uploadUrl}
onChange={handleUpload}
accept="image/jpg,image/png,image/jpeg"
listType="picture"
>
<a style={{ color: '#FFF' }}>重新上传</a>
</Upload>
</>
}
trigger="hover"
>
<img
src={filePri+imageUrl}
width={128}
height={128}
/>
</Tooltip>
:
<Upload
showUploadList={false}
action={uploadUrl}
onChange={handleUpload}
accept="image/jpg,image/png,image/jpeg"
listType="picture"
>
<div
style={{ width: 128, height: 128, cursor: 'pointer', ...style }}
className={classnames(styles.btn, className)}
>
<div className={styles.upload}>
<span style={{ fontSize: 24 }}>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
</span>
<div style={{ fontSize: 16 }}>{uploadText || '上传'}</div>
</div>
</div>
</Upload>
}
</>
);
}
}
.btn{
border: 1px dashed #d9d9d9;
width: 104px;
height: 104px;
border-radius: 4px;
background-color: #fafafa;
text-align: center;
cursor: pointer;
-webkit-transition: border-color 0.3s ease;
transition: border-color 0.3s ease;
vertical-align: top;
margin-right: 8px;
margin-bottom: 8px;
display: table;
}
.btn > .upload{
width: 100%;
height: 100%;
display: table-cell;
text-align: center;
vertical-align: middle;
padding: 8px;
}
设置上传文件的后台接口地址与显示文件的文件服务器地址
2. 批量上传文件,支持一次上传多个,可删除。效果图如下
页面调用代码
<FormItem
{...formItemLayout}
label="课件资源"
>
{getFieldDecorator('goodsImage', {
initialValue: mainImages.length > 0 ? mainImages[0] : null,
})(
<div>
<Upload
accept="application/x-shockwave-flash,video/mp4,audio/mp3,image/gif,image/png,image/jpeg"
showUploadList={false}
action={`${apiUri}/upload/file`}
multiple
onChange={this.handleChange}
>
<Button>
<Icon type="upload" /> 上传图片
</Button>
</Upload>
{
mainImages.length > 0 ?
<UploadList items={mainImages} clearImages={this.clearImages} /> : null
}
</div>
)}
</FormItem>
上传文件与删除文件方法
let uuid = 100000;
state = {
mainImages: [],
};
handleChange = (info) => {
const { mainImages = [] } = this.state;
uuid++;
if (info.file.status === 'done') {
if(info.file.response.statusCode === 1) {
const url = info.file.response.data;
const list = mainImages.concat(url);
this.setState({mainImages: list});
}
}
};
clearImages = (item) => {
this.setState({ mainImages: item });
};
批量上传文件组件
import React, { Component } from 'react';
import { Icon } from 'antd';
import { fileUri } from '@/constant';
const grid = 8;
class Index extends Component {
constructor(props) {
super(props);
this.state = {
items: this.props.items,
};
}
componentWillReceiveProps(props) {
const { items } = props;
this.setState({
items,
});
}
getListStyle = {
display: 'flex',
padding: grid,
overflow: 'auto',
};
getItemStyle = {
userSelect: 'none',
margin: `0 ${grid}px 0 0`,
};
clearImage = (imageUrl) => {
const items = this.state.items.filter(key => key !== imageUrl);
const { clearImages } = this.props;
clearImages(items);
};
render() {
const { items } = this.state;
return (
<div>
<div
style={this.getListStyle}
>
{items ? items.map((item, index) => (
<div style={{ position: 'relative' }} index={index} key={item}>
<img
src={fileUri+item}
width={128}
height={128}
style={this.getItemStyle}
/>
<span style={{ position: 'absolute', right: '8%', top: '-10%' }}>
<a onClick={() => this.clearImage(item)}><Icon
type="delete"
style={{ color: 'red' }}
/>
</a>
</span>
</div>
)) : null}
</div>
</div>
);
}
}
export default Index;
批量上传文件组件适用于图片上传,超过宽度会显示滚动条,可根据具体需求更改样式。
3. 批量文件上传,适用于音频,视频文件等,展示文件链接,可点击跳转,可删除,效果图如下。
页面调用代码,文件上传与文件删除方法与批量上传图片组件调用一致。
批量上传文件组件如下。
import React, { Component } from 'react';
import { Icon } from 'antd';
import { fileUri } from '@/constant';
class Index extends Component {
constructor(props) {
super(props);
this.state = {
items: this.props.items,
};
}
componentWillReceiveProps(props) {
const { items } = props;
this.setState({
items,
});
}
clearImage = (imageUrl) => {
const items = this.state.items.filter(key => key !== imageUrl);
const { clearImages } = this.props;
clearImages(items);
};
render() {
const { items } = this.state;
return (
<div>
<div>
{items ? items.map((item, index) => (
<div index={index} key={item}>
{
item ?
<a>{fileUri+item}</a>
: null
}
<a style={{ marginLeft: 5 }} onClick={() => this.clearImage(item)}><Icon
type="delete"
style={{ color: 'red' }}
/>
</a>
</div>
)) : null}
</div>
</div>
);
}
}
export default Index;
单个文件上传与批量文件上传都是通过控制state的,上传文件方法即调用后台的上传文件方法,拿到后台返回的文件地址,放入state里面即可。
Ant Design Upload上传官方文档地址
https://ant.design/components/upload-cn/