【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】图片自定义上传组件 超详细含代码及解读~ 的相关文章

  • 如何检测浏览器是否支持自定义元素

    我正在查看 Modernizr 它应该有助于功能检测 这应该可以帮助确定您的网站是否与给定的 Web 浏览器兼容 但我没有看到任何表明我可以使用它来检测自定义 HTML 的内容我们在内容中创建和定义的元素 如果不是 Modernizr 我如
  • JavaScript onTouch 不工作

    谁能告诉我为什么这个 onTouch 处理程序没有触发 var myDiv document getElementById existingContent var myButton a href log out a myDiv append
  • 尝试将布尔 C# 变量传递给 javascript 变量并将其设置为 true

    在我的 aspx 页面中 我将布尔变量 C 传递给需要布尔类型的 javascript 函数 但遇到了问题 但是 C 变量返回 True 而 javascript 不喜欢大写 myjavascript 如果我将 c 变量转换为字符串 那么我
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 如何防止 Iframe 在与浏览器交互后弄乱浏览器的历史记录?

    因此 就我而言 我使用 Iframe 将 Grafana 附加到我的页面 这为我提供了漂亮且易于使用的图表 可以注意到 每次在图表上进行放大或缩小 使用鼠标单击 交互后 Grafana 的 Iframe 都会在我的 Angular 页面上触
  • Meteor:应用程序无法在 0.9.1.1 版本上运行

    出现类似错误 Error TypeError undefined is not a function evaluating Template create anonymous function iron dynamic template j
  • 在 Wordpress 站点中进行 AJAX 调用时出现问题

    我在使用 Wordpress 站点功能的 AJAX 部分时遇到了一些问题 该功能接受在表单上输入的邮政编码 使用 PHP 函数来查找邮政编码是否引用特定位置并返回到该位置的永久链接 我的第一个问题是关于我构建的表单 现在我的表单操作是空白的
  • Javascript正则表达式用于字母字符和空格? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我需要一个
  • Node.js:如何在检索数据(块)时关闭响应/请求

    我正在用 node js 构建一个应用程序 它加载多个页面并分析内容 因为 node js 发送块 所以我可以分析这些块 如果一个块包含例如索引 nofollow 我想关闭该连接并继续其余部分 var host example com to
  • 除了更改标题之外,如何在 Firefox 中强制另存为对话框?

    有没有办法在 ff 中强制打开 www example com example pdf 的另存为对话框 我无法更改标题 如果您可以将文件以 Base64 格式输出到客户端 则可以使用 data uri 进行下载 location href
  • Jquery/Javascript 上传和下载文件,无需后端

    是否可以在没有后端服务器的情况下在 JavaScript 函数中下载和上传文件 我需要导出和导入由 JavaScript 函数生成的 XML 我想创建按钮 保存 xml 来保存文件 但我不知道是否可行 另一方面 我希望将 XML 文件直接上
  • 使用 KnockoutJs 映射插件进行递归模板化

    我正在尝试使用以下方法在树上进行递归模板化ko映射 插入 http knockoutjs com documentation plugins mapping html 但我无法渲染它 除非我定义separate每个级别的模板 在以下情况下
  • 在javascript中解析json - 长数字被四舍五入

    我需要解析一个包含长数字的 json 在 java servlet 中生成 问题是长数字被四舍五入 当执行这段代码时 var s x 6855337641038665531 var obj JSON parse s alert obj x
  • Babel 7 Jest Core JS“TypeError:wks不是函数”

    将我的项目升级到 Babel 7 后 通过 Jest 运行测试会抛出以下错误 测试在 Babel 6 中运行没有任何问题 但在 Babel 7 中失败并出现以下错误 TypeError wks is not a function at Ob
  • Javascript 数组到 VBScript

    我有一个使用 Javascript 构建的对象数组 我需要使用 VBScript 读取它 如下例所示 我找不到在 VbScript 代码中循环遍历数组的方法myArray object 这个例子是我的问题的简化 我无法更改页面的默认语言 这
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 为 illustrator 导出脚本以保存为 web jpg

    任何人都可以帮我为 illustrator CC2017 编写一个脚本 将文件以 JPG 格式导出到网络 旧版 然后保存文件并关闭 我有 700 个文件 每个文件有 2 个画板 单击 文件 gt 导出 gt 另存为 Web 旧版 然后右键文
  • 如何获取给定 DOM 元素的所有定义的 CSS 选择器?

    如何使用 jQuery 获取给定 DOM 元素的所有定义的 CSS 选择器 定义后 我的意思是在应用于任何样式表的所有 CSS 选择器document 在某种程度上 这类似于 FireBug 实现的功能 其中显示所选 DOM 元素的所有应用
  • 在 React.js 中编辑丰富的数据结构

    我正在尝试为数据结构创建一个简单的基于网格的编辑器 但我在使用 React js 时遇到了一些概念问题 他们的文档对此没有太大帮助 所以我希望这里有人可以提供帮助 首先 将状态从外部组件传输到内部组件的正确方法是什么 是否有可能将内部组件中

随机推荐

  • 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