利用React+Ant Design 的Upload组件进行封装的上传多个图片的照片墙组件

利用React+Ant Design 的Upload组件进行封装的上传多个图片的照片墙组件

Antd 提供了对文件上传的Upload组件,个人感觉还是非常好用的。在公司里,如果使用了Antd,那么Upload必定是要封装成一个单独的组件的。下面的代码是对Upload组件进行的封装,自认为注释已经比较全了。后面也有如何调用这个组件获取到上传后的服务器返回的图片名称。

Antd Upload组件官方指引

直接上代码,这里是封装的Upload组件:


//将图片加工成base64编码形式
function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

 export default class PicturesWall extends Component {
  state = {
    previewVisible: false,    //是否展示预览框
    previewImage: '',         //要预览的图片的地址或者base64编码
    previewTitle: '',
    fileList: [],
  };
  
  //从fileList 提取出所有上传的图片的name的数组 在父组件中通过ref调用该方法获得该数组(这里我返回的是数组)
  getImgArr = () =>{
          let result = this.state.fileList.map((item) =>{
                return item.name;
          });
          return result;
  }
    //重显图片
  setFileList = (imgArr) => {
    let fileList = [];
    imgArr.forEach((item,index) => {
      fileList.push({uid:-index,name:item,url:`${BASE_URL}/upload/${item}`});
    });
    this.setState({fileList});
  }
  
  //关闭预览窗
  handleCancel = () => this.setState({ previewVisible: false });
  
  //展示预览窗
  handlePreview = async file => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }

    this.setState({
      previewImage: file.url || file.preview,
      previewVisible: true,
      previewTitle: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
    });
  };
  //当图片状态发生变化的回调  这里的fileList是antd内部已经封装好了,在调用这个方法时已经将最新的图片对象push到fileList中了,也就是fileList是最新的图片列表
  //file 是操作的当前的图片的信息
  handleChange = async({file,fileList }) => {
      //若文件上传成功 =>请求服务器成功
      if(file.status === 'done'){
        fileList[fileList.length-1].url = file.response.data.url               //response是后台返回的数据,url为服务器返回的图片地址,默认没有url
        fileList[fileList.length-1].name = file.response.data.name             //将图片的name重写为从服务器中返回的name,进行删除操作
        this.getImgArr();
       }
    //    if(file.status === 'error') this.getImgArr();
       if(file.status === 'removed'){
          const result = await reqDeletePicture(file.name);          //这里是封装axios后的方法
          const {status} = result;
          if(status===0) message.success('删除图片成功');
       }
      this.setState({ fileList })
    };

  render() {
    const { previewVisible, previewImage, fileList, previewTitle } = this.state;
    const uploadButton = (
      <div>
        <PlusOutlined />
        <div style={{ marginTop: 8 }}>Upload</div>
      </div>
    );
    return (
      <>
        <Upload
          action={`${BASE_URL}/uploadFile`}                                              //接收图片服务器的地址
          method="post"                                                                  //上传方式
          name="images"                                                                  //参数的key名
          listType="picture-card"                                                        //照片墙的展示方式
          fileList={fileList}                                                            //图片列表
          onPreview={this.handlePreview}                                                 //点击预览按钮的回调
          onChange={this.handleChange}                                                   //图片状态改变的回调
        >
          {fileList.length >= 4 ? null : uploadButton}              
          { /*隐藏上传按钮的图片数量的阈值*/}                      
        </Upload>
        
        {/*这里的是浏览时需要的Modal组件*/}
        <Modal
          visible={previewVisible}
          title={previewTitle}
          footer={null}
          onCancel={this.handleCancel}
        >
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </>
    );
  }
}

在父组件中这样调用:

//在父组件中声明:
pictureList = React.createRef();

//在需要获取的地方调用:
let prictureArr = this.pictureList.current.getImgArr();     //这个是直接返回图片名称数组
//我们在实际使用时,后端接口可能要求我们返回字符串的类型,并以逗号(,)进行分隔
let prictureStr = this.pictureList.current.getImgArr().join()+',';
let priceture = prictureStr.substring(0,prictureStr.length-1);

//重显图片  (images为从服务器返回的数据)
this.pictureList.current.setFileList(images.split(','));

//这是在render方法中的组件声明:
 <PicturesWall ref={this.pictureList}/>  
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.ToString()°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值