现需求就是上传之后的图片再次进入的时候 该组件呈现可预览并且删除之后可以再次上传
图片个数限制最多传3张
效果如图:
图片上传
return (
<>
<Modal visible={visible} maskClosable={false} className={classes.root} title={'添加专题图'} onCancel={() => setAddItemShow(false)}>
<Form {...layout} form={form} initialValues={{ remember: true }} onFinish={(values) => getAnnouncementApi(values)}>
<Form.Item
label="图片"
name="picture"
rules={state == 'add' ? [{ required: true, message: '请上传图片' }] : [{ required: false, message: '请上传图片' }]}>
<Upload
beforeUpload={() => false}
listType="picture-card"
accept=".png,.jpg"
fileList={pictureList}
onPreview={handlePreview}
onChange={({ fileList }) => setpictureList(fileList)}>
{pictureList.length >= 3 ? null : uploadButton}
</Upload>
</Form.Item>
<Form.Item {...tailLayout}>
<Button loading={loadVis} type="primary" htmlType="submit" block>
确定
</Button>
</Form.Item>
</Form>
</Modal>
<Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</>
)
预览
//预览
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getFileBase64(file.originFileObj)
}
setPreviewImage(file.url || (file.preview as string))
setPreviewVisible(true)
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1))
}
回显
//回显
useEffect(() => {
if (state == 'add') { //判断当前是新增还是编辑
setpictureList([])
}
if (!detailVal) return //详情信息
// 获取数据中的图片
if (detailVal?.pictureFiles) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
const files = detailVal?.pictureFiles.map((url) => ({ uid: uuidv4(), name: url.filename, status: 'done', url: url.url }))
setpictureList(files)
// setpictureList(detailVal.pictureFiles)
} else {
setpictureList([])
}
}, [detailVal, state])
这里用到了获取文件的 base64 字符串形式
/**
* 获取文件的 base64 字符串形式
* @param {File} file
* @returns {Promise<string>}
*/
export function getFileBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
}
完成代码下:
import React, { useState, useEffect } from 'react'
import { Modal, Form, Upload, Button, DatePicker, message } from 'antd'
import { createUseStyles } from 'react-jss'
import { CameraOutlined } from '@ant-design/icons'
import { v4 as uuidv4 } from 'uuid'
import { getFileBase64 } from '../workbench-project/utils/helper'
const uploadButton = (
<div>
<CameraOutlined />
<div style={{ marginTop: 8 }}>上传图片</div>
</div>
)
const layout = {
labelCol: { span: 3 },
wrapperCol: { span: 20 },
}
const tailLayout = {
wrapperCol: { offset: 1, span: 22 },
}
interface IProps {
visible: boolean
setAddItemShow: () => void
loadVis:boolean
setloadVis:boolean
postAddThematic: () => void
state:string
detailVal: Record<string, string>
}
const ThematicAddModule: React.FC = (props: IProps) => {
const { setAddItemShow, visible, loadVis, setloadVis, postAddThematic, state, detailVal } = props
const [pictureList, setpictureList] = useState([])
const [previewVisible, setPreviewVisible] = useState(false)
const [previewImage, setPreviewImage] = useState('')
const [previewTitle, setPreviewTitle] = useState('')
//预览
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getFileBase64(file.originFileObj)
}
setPreviewImage(file.url || (file.preview as string))
setPreviewVisible(true)
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1))
}
//关闭窗口
const handleCancel = () => setPreviewVisible(false)
//回显
useEffect(() => {
if (state == 'add') { //判断当前是新增还是编辑
setpictureList([])
}
if (!detailVal) return //详情信息
// 获取数据中的图片
if (detailVal?.pictureFiles) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
const files = detailVal?.pictureFiles.map((url) => ({ uid: uuidv4(), name: url.filename, status: 'done', url: url.url }))
setpictureList(files)
// setpictureList(detailVal.pictureFiles)
} else {
setpictureList([])
}
}, [detailVal, state])
return (
<>
<Modal visible={visible} maskClosable={false} className={classes.root} title={'添加专题图'} onCancel={() => setAddItemShow(false)}>
<Form {...layout} form={form} initialValues={{ remember: true }} onFinish={(values) => getAnnouncementApi(values)}>
<Form.Item
label="图片"
name="picture"
rules={state == 'add' ? [{ required: true, message: '请上传图片' }] : [{ required: false, message: '请上传图片' }]}>
<Upload
beforeUpload={() => false}
listType="picture-card"
accept=".png,.jpg"
fileList={pictureList}
onPreview={handlePreview}
onChange={({ fileList }) => setpictureList(fileList)}>
{pictureList.length >= 3 ? null : uploadButton}
</Upload>
</Form.Item>
<Form.Item {...tailLayout}>
<Button loading={loadVis} type="primary" htmlType="submit" block>
确定
</Button>
</Form.Item>
</Form>
</Modal>
<Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</>
)
}
没有太多文字类的描述,只能用代码表示,这里表示直接复制代码,然后根据需求在改改就大功告成啦!!!