自定义React图片上传组件
现在网上有很多封装好的插件,但是我没有找到适合我们项目需求的,所以自定义封装了这个图片上传组件。该组件是基于React设计的,希望对你有帮助。你也可以去https://github.com/windSandEye/img-upload/tree/master下载我的源码。组件js文件(img-upload.js)import React from 'react';import { Icon, Mo
·
现在网上有很多封装好的插件,但是我没有找到适合我们项目需求的,所以自定义封装了这个图片上传组件。该组件是基于React
设计的,希望对你有帮助。你也可以去https://github.com/windSandEye/img-upload/tree/master下载我的源码。
属性名 | 说明 | 类型 | 默认值 | 可选值 |
---|---|---|---|---|
imgTitle | 组件的中文描述 | String | “” | |
height | 图片外框的高度 | String | 200px | |
renderState | 图片初始化状态 | String | init | init,loading,upload |
imgSrc | 图片src路径 | String | “” | |
titleClass | 文本描述信息的样式 | String | “” | |
disabled | 是否禁用组件 | Boolean | false | true或false |
accept | 接受的图片类型 | String | “*” | jpg,png,gif等 |
事件 | 说明 | 参数 | 返回值 |
---|---|---|---|
getImgFile | 获取图片文件信息 | {file:图片文件,src:图片src} | |
resetImgSrc | 重置图片信息 |
import React from 'react';
import { Icon, Modal } from 'antd';
import PropTypes from 'prop-types';
import './img-upload.css'
export default class ImgUpload extends React.Component {
/*
组件属性
id:组件动态标识,表明组件是否需要修改的唯一标识
imgTitle:组件的中文描述
height:图片外框的高度
imgFile:图片文件
renderState:图片初始化状态,//init:初始化,loading:正在上传,upload:上传成功
imgSrc:图片src路径
isPreview: false//是否显示弹出层预览全图
titleClass:"" //文本描述信息的样式
getImgFile:function():获取图片文件信息
*/
constructor(props) {
super(props)
this.state = {
imgFile: null,
imgSrc: this.props.imgSrc||"",
renderState: this.props.renderState||"init",
isPreview: false,
disabled:this.props.disabled || false
}
}
static defaultProps = {
imgTitle: "",
height: "200px",
renderState: "init",
imgSrc: "",
titleClass: "",
accept:"*"
}
static propTypes = {
imgTitle: PropTypes.string,
renderState: PropTypes.oneOf(['init', 'loading', 'upload']),
imgSrc: PropTypes.string,
titleClass: PropTypes.string,
accept:PropTypes.string
};
componentWillReceiveProps(nextProps){
if(this.props.imgSrc != nextProps.imgSrc){
this.setState({imgSrc:nextProps.imgSrc})
}
if(this.props.renderState != nextProps.renderState){
this.setState({renderState:nextProps.renderState})
}
if(this.props.disabled != nextProps.disabled){
this.setState({disabled:nextProps.disabled})
}
}
renderInit() {//初始化渲染
return (
<div className="img-box" style={{ height: this.props.height }}>
<input type="file" className="img-file" onChange={this.imgChange.bind(this)} accept={this.props.accept} />
<div className={"img-add " + this.props.titleClass}>
<Icon type="plus" className="img-add-icon" />
<div>{this.props.imgTitle}</div>
</div>
</div>
)
}
renderLoading() {//正在上传
return (
<div className="img-box" style={{ height: this.props.height }}>
<img src="/static/admin/img/loading.gif" className="img-loading" />
</div>
)
}
renderUpload() {//上传完成
const imgSrc = (this.state.imgSrc&&this.state.imgSrc!="")?this.state.imgSrc:"/static/admin/img/error_img.jpg"
const imgBox = this.state.disabled ? "img-box-preview-hide" : "img-box-preview-show"
return (
<div className={imgBox} style={{ height: this.props.height }}>
<img src={imgSrc} className="img-wh" />
<div className="img-preview">
<Icon type="eye-o" className="img-operate" onClick={this.original.bind(this)} />
<Icon type="delete" className="img-operate" onClick={this.deleteImg.bind(this)} />
</div>
</div>
)
}
renderImg() {
if (this.state.renderState === "init") {
return this.renderInit()
} else if (this.state.renderState === "loading") {
return this.renderLoading()
} else if (this.state.renderState === "upload") {
return this.renderUpload()
}
}
imgChange(event) {//获取文件图片
this.setState({ imgFile: event.target.files[0], renderState: "loading" }, () => {
this.previewImg()
})
}
previewImg() {//本地预览
const that = this;
const file = this.state.imgFile;
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
that.setState({ renderState: "upload", imgSrc: this.result })
}
}
original() {//原图查看
this.setState({ isPreview: true })
}
deleteImg() {//删除图片
this.setState({ renderState: "init", imgFile: null, isPreview: false, imgSrc: "" })
}
resetImgSrc(){
this.setState({ renderState: this.props.renderState, imgFile: null, imgSrc: this.props.imgSrc })
}
getImgFile() {
return {file:this.state.imgFile,src:this.state.imgSrc}
}
cancelModal() {//关闭弹窗
this.setState({ isPreview: false })
}
render() {
return (
<div>
{this.renderImg()}
<Modal visible={this.state.isPreview} footer={null}
onCancel={this.cancelModal.bind(this)}
width="auto" wrapClassName="img-center"
style={{ display: "inline-block" }}
>
<img src={this.state.imgSrc} className="preview-all" />
</Modal>
</div>
)
}
}
组件css文件(img-upload.css)
.img-box{
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
margin-left:30px;
margin-right:30px;
}
.img-box-preview-show{
border: 1px solid #d9d9d9;
border-radius: 6px;
cursor: pointer;
margin-left:30px;
margin-right:30px;
}
.img-box-preview-hide{
border: 1px solid #d9d9d9;
border-radius: 6px;
cursor: pointer;
margin-left:30px;
margin-right:30px;
}
.img-file{
position: absolute;
top: 50%;
left: 50%;
width: 36px;
height: 36px;
z-index: 9999;
margin-left: -18px;
margin-top: -41px;
opacity: 0;
filter:Alpha(opacity=0);
}
.img-add {
width: 130px;
text-align: center;
position: absolute;
top: 50%;
margin-top: -32px;
left: 50%;
margin-left: -65px;
}
.img-add-icon{
font-size: 24px;
font-weight: bold;
}
.img-preview{
display: none;
position: absolute;
top:50%;
left:50%;
margin-top:-22px;
margin-left:-44px;
}
.img-box-preview-show:hover .img-preview{
display:block;
}
.img-operate{
font-size:24px;
margin:10px;
color: red;
}
.img-loading{
position: absolute;
top:50%;
left:50%;
margin-top:-50px;
margin-left:-50px;
}
.preview-all {
width:100%;
}
.img-center{
text-align: center;
}
.img-wh{
width:100%;
height:100%;
}
使用方法
<ImgUpload
imgTitle="国家首页配图(1920*470)"
height="320px"
id={this.props.countryInfo._id}
imgSrc={this.props.countryInfo.bannerPath}
ref="bannerPath"
renderState={this.props.countryState == "add" ? "init" : "upload"} />
我们可以根据ref获取到该组件,然后调用组件的方法获取图片文件,之后文件的保存就是你按部就班的插入数据库就行了。例如: const bannnerFile = this.refs.bannerPath.getImgFile();
效果图
初始化
添加图片后
预览原图
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献2条内容
所有评论(0)