Ant-Desgin 头像上传框
样式图
图片数量限制为
1
,当选择了图片后,需要切换图像时需点击头像完成切换
参数
js
/**
* @description: 图片上传组件
* @param {*} action: 上传地址
* @param {*} width: 宽度
* @param {*} height: 高度
* @param {*} onFileListChange: 文件列表改变的回调函数
* @return {*}
*/
<FileUpload action={"/upload"} width={100} height={100} onFileListChange={handleFileListChange} />
主要代码
UpLoad 组件
js
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-unused-vars */
import React, { useEffect, useState, useRef } from 'react'
import { Upload, message } from 'antd'
import PropTypes from 'prop-types'
import ImgCrop from 'antd-img-crop'
const FileUpload = ({ action, width = 100, height = 100, onFileListChange }) => {
const [fileList, setFileList] = useState([])
const [imgUrl, setImgUrl] = useState('')
const uploadRef = useRef(null)
const imgStyle = {
width: `${width}px`,
height: `${height}px`,
objectFit: 'cover',
borderRadius: '50%',
cursor: 'pointer'
}
useEffect(() => {}, [])
FileUpload.propTypes = {
action: PropTypes.string.isRequired,
width: PropTypes.number,
height: PropTypes.number,
onFileListChange: PropTypes.func
}
const onChange = async ({ fileList: newFileList }) => {
const src = await new Promise(resolve => {
const reader = new FileReader()
reader.readAsDataURL(newFileList[0].originFileObj)
reader.onload = () => resolve(reader.result)
})
setImgUrl(src)
setFileList(newFileList)
// 调用父组件传递的回调函数
onFileListChange(newFileList)
}
const onPreview = async file => {
const src = await new Promise(resolve => {
const reader = new FileReader()
reader.readAsDataURL(file.originFileObj)
reader.onload = () => resolve(reader.result)
})
const image = new Image()
image.src = src
const imgWindow = window.open(src)
imgWindow?.document.write(image.outerHTML)
}
const beforeUpload = async file => {
console.log('beforeUpload')
const isLt12M = file.size / 1024 / 1024 < 12
const isImage = file.type.startsWith('image/')
if (!isLt12M) {
message.error('图片不得大于12MB!')
}
if (!isImage) {
message.error('只允许上传图片!')
}
return isLt12M && isImage
}
const handleImageClick = () => {
const uploadInput = document.querySelector('.ant-upload input[type="file"]')
if (uploadInput) {
uploadInput.click()
}
}
return (
<>
<ImgCrop>
<Upload
action={action}
ref={uploadRef}
listType="picture-circle"
fileList={fileList}
onChange={onChange}
onPreview={onPreview}
beforeUpload={beforeUpload}
showUploadList={false}
maxCount={1}
>
{fileList.length < 1 && '+ Upload'}
</Upload>
</ImgCrop>
{fileList.length > 0 && (
<div>
<img src={imgUrl} alt="avatar" style={imgStyle} onClick={handleImageClick} />
</div>
)}
</>
)
}
export default FileUpload
父组件
js
/* eslint-disable no-unused-vars */
import React, { useEffect, useState } from 'react'
import FileUpload from '.'
const Demo = () => {
const [parentFileList, setParentFileList] = useState([])
const handleFileListChange = (newFileList) => {
// 更新父组件的文件列表
setParentFileList(newFileList)
}
useEffect(() => {
console.log(parentFileList, 666);
}, [parentFileList, setParentFileList])
return (
<div>
<FileUpload action={"/upload"} width={100} height={100} onFileListChange={handleFileListChange} />
</div>
)
}
export default Demo