【AntDesign】图片自定义上传组件 超详细含代码及解读~

2023-11-03

技术栈

AntDesign 版本 : 3x

效果图如下
官网示例给的是标准上传模式, 此处用的是自定义上传模式(customRequest)
在这里插入图片描述
在这里插入图片描述

代码

子组件代码 ↓

import React, { useState, useImperativeHandle } from 'react'
import PropTypes from 'prop-types'
import { Modal, Upload, Icon } from 'antd'
import styles from './ImgUpload.less'
import { uploadFunc } from '../../common/uploadFunc'

const getBase64 = file =>
  new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })

const ImgUpload = (props, ref) => {
  // dataList - 父组件传入的图片列表, 数据接口可参考官网
  // maxCount - 父组件传入的上传图片数量的最大值, 可控制单张或多张图片
  // disabled - 父组件传入的控制组件是否禁止上传
  // handleMediaResource - 与父组件进行数据通信
  
  const { dataList, maxCount, type, disabled, handleMediaResource } = props
  const [previewOpen, setPreviewOpen] = useState(false)
  const [previewImage, setPreviewImage] = useState('')
  const [previewTitle, setPreviewTitle] = useState('')
  const [fileList, setFileList] = useState(dataList)
  const handleCancel = () => setPreviewOpen(false)
  
  // 父组件提交数据时, 重置该子组件数据
  useImperativeHandle(ref, () => ({ clearUploadList }))
  const clearUploadList = () => {
    setFileList([])
  }
  
  // 是否允许显示删除按钮
  // 只读时, 不允许用户进行删除操作
  const showUploadList = { showRemoveIcon: disabled ? false : true }

  // 图片点击放大查看
  const handlePreview = async file => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj)
    }
    setPreviewImage(file.url || file.preview)
    setPreviewOpen(true)
    setPreviewTitle(
      file.name || file.url.substring(file.url.lastIndexOf('/') + 1)
    )
  }
  const handleChange = ({ fileList: newFileList }) => {
  }

  // base64转Blob
  const base64ToBlob = code => {
    const parts = code.split(';base64,')
    const contentType = parts[0].split(':')[1]
    const raw = window.atob(parts[1])
    const rawLength = raw.length
    const uInt8Array = new Uint8Array(rawLength)
    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i)
    }
    return new Blob([uInt8Array], { type: contentType })
  }

    // 自定义上传逻辑
    const customRequest = async options => {
    const { file, filename, data } = options
	
	// uploadFunc 是服务器上传操作
    const base64 = await getBase64(file)
    const suffixs = ['jpg', 'jpeg', 'png']
    const usage = 'picture'
    uploadFunc(file, suffixs, usage)
      .then(res => {
        const newImgList = [
          ...fileList,
          {
            uid: file.uid,
            name: file.name,
            status: 'done',
            url: res.path,
            // url: URL.createObjectURL(base64ToBlob(base64)),
            lastModified: file.lastModified,
            lastModifiedDate: file.lastModifiedDate,
            originFileObj: file,
            percent: 100,
            thumbUrl: base64,
            type: file.type,
          },
        ]
        // 更新图片列表数据
        setFileList(newImgList)
        if (newImgList.length > 0) {
          handleMediaResource({ type, fileList: newImgList })
        }
      })
      .catch(err => {
        const newFileList = [
          ...fileList,
          {
            uid: file.uid,
            name: file.name,
            status: 'error',
            url: file.path,
            lastModified: file.lastModified,
            lastModifiedDate: file.lastModifiedDate,
            originFileObj: file,
            percent: 100,
            type: file.type,
          },
        ]
        setFileList(newFileList)
      })
  }

  const props2 = {
    accept: props.acceptType,
    // 删除已上传数据
    onRemove: file => {
      const index = fileList.indexOf(file)
      const newFileList = fileList.slice()
      newFileList.splice(index, 1)
      setFileList(newFileList)
    },
  }

  const uploadButton = (
    <div>
      <Icon style={{ fontSize: '18px' }} type="upload" />
      <div
        style={{
          marginTop: 8,
        }}
      >
        Upload
      </div>
    </div>
  )
  return (
    <div>
      <Upload
        {...props2}
        listType="picture-card"
        fileList={fileList}
        disabled={disabled}
        showUploadList={showUploadList}
        onPreview={handlePreview}
        onChange={handleChange}
        customRequest={customRequest}
      >
        {fileList.length >= maxCount ? null : uploadButton}
      </Upload>
      
      <Modal
        centered
        width={700}
        // 注意 : 这儿3.x展示modal属性是visible,5.x是open
        visible={previewOpen}
        title={previewTitle}
        footer={null}
        onCancel={handleCancel}
      >
        <img
          alt="example"
          style={{
            width: '100%',
          }}
          src={previewImage}
        />
      </Modal>
    </div>
  )
}

export default React.forwardRef(ImgUpload)

父组件(部分)代码 ↓

  // 通过ref向子组件传递事件
  const uploadImgComRef = React.createRef(null)

  // 提交时清除图片组件数据
  const onSubmitFn = e => {
  	uploadImgComRef.current.clearUploadList()
  }
  
  // 上传组件
  <ImgUpload
    ref={uploadImgComRef}
    acceptType=".jpg,.jpef,.png"
    maxCount="1"
    dataList={imgDataList}
    disabled={editType == 'view' ? true : false}
    handleMediaResource={handleMediaResource}
  />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【AntDesign】图片自定义上传组件 超详细含代码及解读~ 的相关文章

随机推荐

  • vue的创建问题和axios问题

    文章思路来源于网络以及自己的尝试和理解 使用命令行执行vue相关的npm命令的前提 下载nodejs 版本不要太旧 下载nodejs时会自动下载npm的相关的包 并在安装nodejs时注意环境变量 特别时对npm的环境变量的添加 的添加 v
  • 【Nginx 】nginx的正则表达式

    1 nginx配置基础 1 正则表达式匹配 区分大小写匹配 不区分大小写匹配 和 分别为区分大小写不匹配及不区分大小写不匹配 以什么开头的匹配 以什么结尾的匹配 转义字符 可以转 等 代表任意字符 2 文件及目录匹配 f和 f用来判断是否存
  • AS608指纹识别模块+STM32实现指纹录入

    视频演示 d9148ed412b24119db81eef6c2c8e9ec 1 特性参数 资料来自ALIENTEK文档 ATK AS608 指纹识别模块是 ALIENTEK 推出的一款高性能的光学指纹识别模块 ATK AS608 模块采用了
  • git 下拉使用方法

    1 新建文件 新建的文件是用来关联远程仓库 可进行下拉和上传操作 新建的方法有很多中 选择一种自己认为比简单的即可 2 通过文件打开git bash 用鼠标右键点击所需文件 点击 git bash here 选项 打开后出现 gitC Us
  • 五款拿来就能用的炫酷表白代码

    作者主页 士别三日wyx 作者简介 CSDN top100 阿里云博客专家 华为云享专家 网络安全领域优质创作者 推荐专栏 小白零基础 Python入门到精通 五款炫酷表白代码 1 无限弹窗表白 2 做我女朋友好吗 不同意就关机 3 爱心发
  • 12.网络爬虫—线程队列详讲(实战演示)

    网络爬虫 线程队列详讲与实战 线程 队列 Queue模块介绍 线程和队列的关系 生产者消费者模式 实战演示 王者荣耀照片下载 使用生产者消费者模式 前言 个人简介 以山河作礼 Python领域新星创作者 CSDN实力新星认证 第一篇文章 1
  • angular2 组件的生命周期钩子

    按照生命周期执行的先后顺序 Angular生命周期接口如下所示 名称 时机 接口 范围 ngOnChanges 当被绑定的输入属性的值发生变化时调用 首次调用一定会发生在 ngOnInit之前 OnChanges 指令和组件 ngOnIni
  • Open3D 手动裁剪点云

    目录 一 概述 1 主要函数 2 基础操作 二 代码实现 三 结果展示 四 相关链接 一 概述 Open3d中的VisualizerWithEditing类提供了图形用户交互功能 draw geometries with editing p
  • Java 线程创建方法

    除了继承Thread 实现Runnable Callable三种创建线程方式外的第四种创建方式 实现java util concurrent ThreadFactory接口 实现newThread Runnable r 方法 这种方式应用于
  • 线上CPU飙升排查

    背景 cpu idle下降50 full gc触发线上报警 处理 1 top命令 查看所有进程占用CPU的排序 第一个就是我们的java服务进程 或者jps命令直接查看java服务进程 2 top Hp 46845 查看进程下所有线程占用C
  • 区块链入门之windows 安装以太坊 ethereum 客户端 (win7-64)

    以太坊 Ethereum 是一个运行智能合约的去中心化平台 Platform for Smart Contract 平台上的应用按程序设定运行 不存在停机 审查 欺诈 第三方人为干预的可能 以太坊平台由 Golang C Python 等多
  • Tomcat部署服务器添加多个<Host>就加载多次项目问题《解决方案》

    如题 项目部署到阿里云服务器之后 配置tomcat一个域名同时又可以使用IP直接访问项目 配置是如下
  • vue-router详解 - 从使用到扩展

    1 认识路由 1 1 后端路由 早期的网站开发整个HTML页面是由服务器来渲染的 服务器直接生产渲染好对应的HTML页面 返回给客户端进行展示 但是 一个网站 这么多页面服务器如何处理呢 一个页面有自己对应的网址 也就是URL URL会发送
  • Pychram:踩坑记录/窍门分享

    Debug Console 当使用PyCharm的Debug模式时 最好用的莫过于Debug Console 它与断点相配合可以实现类似于Jupyter Notebook的逐块运行代码的效果 但是今天我突然发现Debug Console无法
  • 用户体验式UI设计

    用户体验式UI设计 1 什么是用户体验式设计 产品的业务化和易用性始终是我们追求的目标 随着 Net Framework 3 0的推出 Windows Presentation Foundation WPF 组件库把用户UI
  • openGL之API学习(三十七)如何从FBO中读取颜色、深度信息

    方法一 保存成图片 QImage img new QImage WINDOW WIDTH WINDOW HEIGHT QImage Format ARGB32 uchar tmpBIT img gt bits 从颜色缓冲区中读取数据 int
  • C++整型(short,int,long,longlong)

    C 整型数据类型 整型就是没有小数部分的 C 基本整型有char short int long long long 由于char 类型比较特殊 下面只关于char int long long long 1 整型short int long
  • 使用verilog实现4选1数据选择器的几种方法

    第一种方法module mux d1 d2 d3 d4 se1 se2 dout input d1 input d2 input d3 input d4 input se1 input se2 output dout reg dout al
  • 一目了然凉哥为大家倾力打造的付费专栏

    写在前面 大家好 我是几何心凉 欢迎来到我的付费专栏系列 本专栏将深入介绍 Vue 3 和 Vite 以及如何在 TypeScript 的帮助下构建现代化的 Web 应用程序 Vue 是一个流行的 JavaScript 框架 它允许开发人员
  • 【AntDesign】图片自定义上传组件 超详细含代码及解读~

    技术栈 AntDesign 版本 3x 效果图如下 官网示例给的是标准上传模式 此处用的是自定义上传模式 customRequest 代码 子组件代码 import React useState useImperativeHandle fr