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

技术栈

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}
  />
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design Vue 是一个基于 Vue.js 的 UI 组件库,提供了丰富的 UI 组件和交互式 UI 设计,可以快速构建优秀的前端界面。如果你想要自定义 Ant Design Vue 组件并使用它们,可以按照下面的步骤进行: 1. 创建自定义组件 创建一个 Vue 组件文件,并在其中定义你的自定义组件。例如,你可以创建一个名为 MyButton 的组件代码如下: ``` <template> <button class="my-button" @click="handleClick"> {{ buttonText }} </button> </template> <script> export default { name: 'MyButton', props: { buttonText: { type: String, default: 'Click me' } }, methods: { handleClick() { this.$emit('click'); } } }; </script> ``` 在上面的代码中,我们定义了一个名为 MyButton 的组件,它包一个按钮和一个点击事件。组件接受一个名为 buttonText 的 prop,用于指定按钮文本的内容。 2. 注册自定义组件 在你的应用程序中注册自定义组件。你可以在全局范围内注册组件,也可以在局部范围内注册组件。例如,在全局范围内注册 MyButton 组件代码如下: ``` import Vue from 'vue'; import MyButton from '@/components/MyButton.vue'; Vue.component('MyButton', MyButton); ``` 在上面的代码中,我们通过 import 引入了 MyButton 组件,并通过 Vue.component() 方法在全局范围内注册了该组件。 3. 使用自定义组件 在你的应用程序中使用自定义组件。你可以在模板中使用自定义组件,也可以在其他组件中使用自定义组件。例如,在模板中使用 MyButton 组件代码如下: ``` <template> <div> <MyButton :buttonText="'Click me!'" @click="handleButtonClick" /> </div> </template> <script> export default { name: 'MyPage', methods: { handleButtonClick() { console.log('Button clicked!'); } } }; </script> ``` 在上面的代码中,我们在模板中使用了 MyButton 组件,并传递了一个名为 buttonText 的 prop,以指定按钮文本的内容。我们还添加了一个点击事件处理程序,以在按钮被点击时打印一条消息。 这就是如何在 Ant Design Vue 中创建自定义组件并使用它们的基本步骤。你可以根据你的需要进行更改和扩展,以创建你自己的自定义组件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值