antd的Upload上传组件,搭配react-cropper实现图片的裁剪上传

实现效果
在Upload上传前,对图片进行裁剪,裁剪完毕后,再交给Upload完成上传。

实现方式

  1. 在Upload的beforeUpload中调起react-cropper进行图片裁剪;
  2. 将拿到的图片传给react-cropper;
  3. 利用react-cropper进行裁剪;
  4. 将裁剪后的图片交给Upload完成上传。

需要解决的问题

  • 如何在beforeUpload中调起react-cropper组件;
  • 裁剪后的图片如何再交给Upload组件。

解决方式

  • 将react-cropper组件放在Modal弹框中,在beforeUpload方法中,调出弹框。
  • Upload的beforeUpload中,支持返回一个 Promise 对象,resolve 时开始上传,resolve可以接收file或blob对象。
  • beforeUpload返回的Promise中设置一个定时器,每隔一段时间,查询一下裁剪是否完成。
  • 设置一个标志位,表示裁剪是否完成。

具体的代码
react-cropper组件

import React, {Component} from 'react'
import { Button } from 'antd'
import Cropper from 'react-cropper'

class CropperDemo extends Component {
  _crop(){}

  handleOk = () => {
  	//将裁剪的图片转成blob对象
    this.refs.cropper.getCroppedCanvas().toBlob((blob) => {
      this.props.onOk(blob);
    },"image/png");
  }
 
  render() {
    const { src } = this.props;
    return (
      <div className="cropper-wrap">
        <Cropper
          ref='cropper'
          src={src}
          style={{height: 400, width: '100%'}}
          aspectRatio={16 / 9}
          guides={false}
          crop={this._crop.bind(this)} 
        />
        <Button onClick={this.handleOk}>确认</Button>
      </div>
    );
  }
}

引用react-cropper组件的代码

// 弹框代码
<Modal visible={cropVisible} footer={null} onCancel={this.handleCropCancel}>
 	<Cropper src={cropSrc} onOk={this.handleOk} />
</Modal>

// onOk方法
handleOk = (dataUrl) => {
 this.setState({
   cropVisible: false
 });
 this.blob= dataUrl;   //  this.blob既是裁剪后的图片,也可以作为裁剪结束的标志
 }

beforeUpload 代码

beforeUpload = (file) => {
   let imageType = ['image/jpeg','image/png','image/jpg','image/gif'];
   let isImage = imageType.findIndex(o => o === file.type) !== -1;
   if (!isImage) {
     message.error('请选择正确的图片类型!');
     return false;
   }
   const isLt2M = file.size / 1024 / 1024 < 2;
   if (!isLt2M) {
     message.error('图片大小不能超过2M!');
     return false;
   }

   let reader = new FileReader();
   reader.readAsDataURL(file); 
   let _this = this;
   reader.onload = (e) => {
     _this.setState({
       cropSrc: e.target.result,
       cropVisible: true,
     })
   }
   return new Promise((resolve, reject) => {
     let index = setInterval(() => {
       if(this.blob){  // 监听裁剪是否完成
         window.clearInterval(index);
         this.blob.uid = file.uid;   // 需要给裁剪后的blob对象设置uid,否则会报错!!!
         resolve(this.blob);   // 执行后续的上传操作
       }
     },100);
   });
 }

利用了setInterval 监听裁剪是否完成,完成后Upload就可以完成后续的上传操作。
好处是不用单独写一个上传方法去,上传裁剪后的图片,整个上传都由Upload完成。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用antd-mobile和react-router-dom来实现tabs功能。首先,你需要安装antd-mobile和react-router-dom依赖包。 ```shell npm install antd-mobile react-router-dom ``` 接下来,你可以创建一个Tabs组件,并在其中使用antd-mobile的TabBar组件实现tabs布局。然后,使用react-router-dom的Route组件来定义每个tab对应的页面。 ```jsx import React from 'react'; import { TabBar } from 'antd-mobile'; import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; const Tabs = () => { const tabItems = [ { title: 'Tab 1', path: '/tab1', component: Tab1 }, { title: 'Tab 2', path: '/tab2', component: Tab2 }, { title: 'Tab 3', path: '/tab3', component: Tab3 }, ]; const renderTabs = () => { return tabItems.map((item) => ( <TabBar.Item key={item.path} title={item.title} icon={<div />} selectedIcon={<div />} selected={window.location.pathname === item.path} onPress={() => { window.location.href = item.path; }} /> )); }; return ( <Router> <div style={{ position: 'fixed', width: '100%', bottom: 0 }}> <TabBar>{renderTabs()}</TabBar> </div> {/* Define routes */} {tabItems.map((item) => ( <Route key={item.path} path={item.path} component={item.component} /> ))} </Router> ); }; const Tab1 = () => <div>Tab 1 content</div>; const Tab2 = () => <div>Tab 2 content</div>; const Tab3 = () => <div>Tab 3 content</div>; export default Tabs; ``` 在上面的代码中,我们定义了三个tab,分别对应不同的路径和组件。通过点击tab,我们可以切换显示不同的内容。你可以根据自己的需求修改tab的数量、标题、路径和对应的组件。 希望这可以帮助你实现antd-mobile和react-router-dom的tabs功能!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值