日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

带你封装一个上传图片组件(ant design+react)

發(fā)布時間:2023/12/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 带你封装一个上传图片组件(ant design+react) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

需求實(shí)現(xiàn)

實(shí)現(xiàn)效果

代碼封裝

UploadImage組件

?備注

?BaseUploadImage組件

index.less

樣式文件

父組件引用


需求實(shí)現(xiàn)

1可以支持上傳最多九張圖片

2圖片支持預(yù)覽 替換 刪除

3支持自定義上傳文件大小 格式 未上傳提示

實(shí)現(xiàn)效果

?

?

?

代碼封裝

UploadImage組件

* @Description: 公共上傳圖片* @param {Array} type 圖片格式。默認(rèn)類型為png,jpeg* @param {Number} size 圖片限制大小 默認(rèn)大小為8M* @param {String} errorTypeMsg 圖片格式錯誤文字提示* @param {String} errorTypeMsg 圖片大小錯誤文字提示* @param {Function} handleFetchUrl 選中圖片后回調(diào)函數(shù)* @param {String} uploadUrl 上傳圖片請求的url,默認(rèn)為admin/fileUpload* @param {String} iconText 按鈕文字* @param {Object} style 樣式* @param {String} value 當(dāng)前圖片地址*/ import React, { Component } from 'react'; import { Tooltip, Upload, Icon, message, Modal, Divider, Spin } from 'antd'; import styles from './index.less'; import { fileUpload } from '@/services/common/upload';export default class UploadImage extends Component {constructor(props) {super(props);this.state = {visible: false,shadow: false,loading: false,};}componentWillMount() {this.props.onRef && this.props.onRef(this);}/*** @description: 上傳前格式大小等校驗(yàn)*/beforeUpload = (file) => {/*** @description: 父組件傳入的參數(shù)* @param {Array} type 圖片格式。默認(rèn)類型為png,jpeg* @param {Number} size 圖片限制大小 默認(rèn)大小為8M* @param {String} errorTypeMsg 圖片格式錯誤文字提示* @param {String} errorSizeMsg 圖片大小錯誤文字提示* @param {Function} checkSize 文件大小校驗(yàn)方式*/let {type = ['image/jpeg', 'image/png', 'image/gif'],size,errorTypeMsg,errorSizeMsg,checkSize,} = this.props;size ? (size = size) : (size = 8);if (checkSize) {size = checkSize(file.type);}const isJpgOrPng = type.includes(file.type);if (!isJpgOrPng) {message.error(errorTypeMsg || '圖片/視頻格式錯誤!請上傳jpeg/png/gif格式圖片或avi/mp4格式視頻');}const isLt8M = file.size < size * 1024 * 1024;if (!isLt8M) {message.error(errorSizeMsg || '圖片/視頻大小限制' + size + 'M!');}return isJpgOrPng && isLt8M;};handleUpload = ({ file }) => {/*** @description:* @param {Function} handleFetchUrl 選中圖片后回調(diào)函數(shù)* @param {String} uploadUrl 上傳圖片請求的url,默認(rèn)為admin/fileUpload*/const { dispatch, uploadUrl, handleFetchUrl } = this.props;const formData = new FormData();formData.append('file', file);formData.append('fileCode', 'PIC');this.setState({ loading: true });const upload = async (record) => {let upUrl = uploadUrl || fileUpload;try {const response = await upUrl(formData);if (response.returnCode === 0) {if (handleFetchUrl && typeof handleFetchUrl === 'function') {handleFetchUrl(response.data, file.type);}message.success('上傳成功');//上傳成功的回調(diào)this.props.handleUploadImage && this.props.handleUploadImage();}this.setState({ loading: false });} catch (error) {console.log(error, 'error');this.setState({ loading: false });}};upload();// dispatch({// type: uploadUrl || 'admin/fileUpload',// payload: formData,// callback: (response) => {// if (response.returnCode === 0) {// if (handleFetchUrl && typeof handleFetchUrl === 'function') {// handleFetchUrl(response.data, file.type);// }// message.success('上傳成功');// }// },// });};/*** @description: 改變visible* @param {*}*/handleSetVisible = (val, event) => {this.setState({visible: val,});if (event) {event.stopPropagation();}};/*** @description: 改變image上的陰影顯示*/setShadow = (val) => {this.setState({shadow: val,});};/*** @description: 刪除圖片*/handleDeleteImg = (event) => {const { dispatch, uploadUrl, handleFetchUrl } = this.props;handleFetchUrl('');if (event) {//函數(shù)刪除的回調(diào)this.props.onHandleDelete && this.props.onHandleDelete();event.stopPropagation();}};render() {/*** @description:* @param {String} iconText 按鈕文字* @param {Object} style 樣式* @param {String} value 內(nèi)容* @param {String} fileType 文件類型 img/video* @param {String} backgroundImg 背景圖,如果是video,縮略圖中顯示背景圖,彈窗大圖中顯示video* @param {String} showDelete 是否顯示刪除按鈕,showDelete=delete 不顯示* @param {Number} size 圖片大小單位M,默認(rèn)8*/const {iconText,style,value,fileType,backgroundImg,disabled,infoText,showDelete,size,errorSizeMsg,errorTypeMsg,} = this.props;console.log(iconText)const { visible, shadow, loading } = this.state;return (<div className={styles.ContentBox}><Spin spinning={loading}><UploadlistType="picture-card"showUploadList={false}customRequest={this.handleUpload}beforeUpload={this.beforeUpload}disabled={disabled}>{value ? (<divclassName={styles.imgContent}style={{width: 150,height: 150,display: 'flex',flexDirection: 'column',alignItems: 'center',justifyContent: 'center',...style,}}onMouseOver={() => this.setShadow(true)}onMouseLeave={() => this.setShadow(false)}>{(fileType === 'img' || !fileType) && (<imgalt={iconText}src={value}style={{maxWidth: (style && style.width && style.width) || 150,maxHeight: (style && style.height && style.height) || 150,}}/>)}{fileType === 'video' && (<imgalt={iconText}src={backgroundImg}style={{maxWidth: (style && style.width && style.width) || 150,maxHeight: (style && style.height && style.height) || 150,}}/>)}{shadow && (<div className={styles.imgShadow}><divclassName={styles.shadowDiv}onClick={(event) => {event.stopPropagation();}}/><div className={styles.shadowDiv}><Tooltip title="放大"><Icontype="zoom-in"onClick={(event) => {this.handleSetVisible(true, event);}}/></Tooltip><Divider type="vertical" style={{ width: 2 }} /><Tooltip title="替換"><Icon type="upload" /></Tooltip>{!disabled && showDelete != 'delete' && (<><Divider type="vertical" style={{ width: 2 }} /><Tooltip title="刪除"><Icontype="delete"onClick={(event) => {this.handleDeleteImg(event);}}/></Tooltip></>)}</div><divclassName={styles.shadowDiv}onClick={(event) => {event.stopPropagation();}}/></div>)}</div>) : (<divstyle={{width: 150,height: 150,display: 'flex',flexDirection: 'column',alignItems: 'center',justifyContent: 'center',...style,}}><Icon type="plus" /><div className="ant-upload-text" style={{ marginTop: 14, whiteSpace: 'normal' }}>{iconText || '上傳圖片'}</div></div>)}</Upload><div style={{ color: '#666', fontSize: '12px', lineHeight: '12px', textAlign: 'center' }}>{infoText ? infoText : ''}</div><ModalmaskClosable={false}maskClosable={false}visible={visible}footer={null}onCancel={() => this.handleSetVisible(false)}>{(fileType === 'img' || !fileType) && (<imgalt={iconText}style={{width: 476,}}src={value}/>)}{fileType === 'video' && (<videoalt={iconText}style={{width: 476,}}src={value}controls/>)}</Modal></Spin></div>);} }

?備注

fileUpload為接口調(diào)用

export function fileUpload(params) {

? return request({ url: `xxxxxxxx`, method: 'form', params });

}

?BaseUploadImage組件

* @Description: 公共上傳圖片* @param {Array} type 圖片格式。默認(rèn)類型為png,jpeg* @param {Number} size 圖片限制大小 默認(rèn)大小為8M* @param {String} errorTypeMsg 圖片格式錯誤文字提示* @param {String} errorTypeMsg 圖片大小錯誤文字提示* @param {Function} handleFetchUrl 選中圖片后回調(diào)函數(shù),目前只在單選中有,適配舊版本* @param {String} uploadUrl 上傳圖片請求的url,默認(rèn)為admin/fileUpload* @param {String} iconText 按鈕文字* @param {Object} style 樣式* @param {String} value 當(dāng)前圖片地址* @param {Boolean} multiple 是否多選* * *@param {String} showDelete 是否顯示刪除按鈕,showDelete=0 不顯示* * @param {Number} size 圖片大小單位M*/ import React, { Component } from 'react'; import { Tooltip, Upload, Icon, message, Modal, Divider } from 'antd'; import styles from './index.less'; import UploadImage from './upload.js';export default class BaseUploadImage extends Component {constructor(props) {super(props);this.state = {imgList: (props.multiple ? props.value : [props.value]) || [''],};}componentWillMount() {this.props.onRef && this.props.onRef(this);window.up = this;}/*** @description: 父組件傳入的默認(rèn)值發(fā)生改變時,更改圖片的默認(rèn)顯示* @param {*} nextProps 最新的props*/componentWillReceiveProps(nextProps) {const {props: { multiple, maxCount = 9 },} = this;const { value } = nextProps;let imgList;if (nextProps.value !== this.props.value) {if (multiple) {imgList = value;if (value && value.length && value.length < maxCount) {imgList.push('');}} else {imgList = [value];}this.setState({imgList: imgList || [''],});}}/*** @description: 上傳圖片回調(diào)* @param {*} val 上傳圖片后服務(wù)器返回的值* @param {*} index 上傳的圖片index,多選時用*/handleSetImg = (val, index) => {const { multiple, maxCount = 9 } = this.props;const { imgList } = this.state;if (multiple) {if (!val && imgList.length > 0) {if (imgList.length === maxCount) {imgList.push('');}imgList.splice(index, 1);} else {imgList[index] = val;if (maxCount > imgList.length) {imgList.push('');}}this.setState({imgList,});} else {this.setState({ imgList: [val] });}};handleChange = () => {this.props.handleDeleteImg && this.props.handleDeleteImg();};handleUploadImg = () => {console.log(22222);this.props.handleUpload && this.props.handleUpload();};/*** @description: 獲取當(dāng)前上傳成功的圖片* @return {*} 當(dāng)前上傳成功的圖片*/getActiveImg = () => {const { multiple, maxCount = 9 } = this.props;const { imgList } = this.state;if (multiple) {//因?yàn)槎噙x的時候,如果沒有上傳到最大可上傳限度,會多出一條數(shù)據(jù),所以如果上傳數(shù)量小于maxCount,需要刪掉最尾的一條數(shù)據(jù)if (maxCount === imgList.length && imgList[imgList.length - 1]) {return imgList;} else {return imgList.slice(0, imgList.length - 1);}} else {return imgList && imgList[0];}};render() {/*** @description:* @param {Boolean} multiple 是否多選* @param {Number} maxCount 多選時,最多可以上傳幾個*/const {multiple,maxCount = 9,iconText,style,fileType,backgroundImg,disabled,infoText,dispatch,showDelete,size,errorSizeMsg,errorTypeMsg,} = this.props;const { imgList } = this.state;return (<div className={styles.ContentBox}>{multiple && (imgList && typeof imgList === 'object' && imgList.length > 0) ? (imgList.map((item, index) => {console.log(item);return (maxCount >= index && (<UploadImageonHandleDelete={() => {this.handleChange();}}handleUploadImage={() => {this.handleUploadImg();}}iconText={iconText}style={style}fileType={fileType}backgroundImg={backgroundImg}disabled={disabled}infoText={infoText}key={index}dispatch={dispatch}value={item}showDelete={showDelete}size={size}errorTypeMsg={errorTypeMsg}errorSizeMsg={errorSizeMsg}handleFetchUrl={this.props.handleFetchUrl || ((val) => this.handleSetImg(val, index))}/>));})) : (<UploadImageonHandleDelete={() => {this.handleChange();}}handleUploadImage={() => {this.handleUploadImg();}}iconText={iconText}style={style}fileType={fileType}backgroundImg={backgroundImg}disabled={disabled}infoText={infoText}dispatch={dispatch}value={imgList[0]}showDelete={showDelete}size={size}errorTypeMsg={errorTypeMsg}errorSizeMsg={errorSizeMsg}handleFetchUrl={this.props.handleFetchUrl || ((val) => this.handleSetImg(val))}/>)}</div>);} }

index.less

樣式文件

.ContentBox {display: inline-block;.imgContent {padding: 8px;position: relative;display: flex;justify-content: center;align-items: center;.imgShadow {width: 100%;height: 100%;position: absolute;background: rgba(0,0,0,0.5);.shadowDiv {height: 33.3333333%;display:flex;justify-content: space-around;color: #fff;align-items: center;font-size: 18px;padding: 0 10px;}}} }

父組件引用

<Form.Item label="上傳圖片"><BaseUploadImageonRef={(ref) => {this.upload = ref;}}value={this.state.themeImgPath}multiple/></Form.Item>

總結(jié)

以上是生活随笔為你收集整理的带你封装一个上传图片组件(ant design+react)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。