自定义input上传图片组件,美化样式

前段时间因为项目需求,做过一个上传图片组件,这里分享下大致思路,希望对有需要的童鞋有所帮助~~~


功能需求:1.上传图片限制大小、分辨率、类型
2.上传图片支持自由裁剪
3.图片上传后支持预览和删除

效果图,只截取了一小部分,大致看下就ok啦,是不是感觉比原生的好看多了^_^

项目是基于react框架写的,话不多说,开始撸代码~~~

Step1:编写基础html结构

<div>
<input
type="file"
accept="image/jpeg, image/gif, image/png, image/bmp"
styleName="input-file"
/>
<label htmlFor="file" styleName="ant-upload">
{uploadButton}
</label>
</div> // uploadButton组件代码如下:
const uploadButton = (
<div styleName="upload-plus-text">
<Icon type="plus" />
<div className="ant-upload-text">上传照片</div>
</div>
);

Step2:基础样式

input-file {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
} .ant-upload {
@w: 100px; width: @w;
height: @w;
padding: 5px;
background-color: #fafafa;
border: 1px dashed #d9d9d9;
border-radius: 4px;
display: block;
cursor: pointer;
position: relative;
} .upload-plus-text {
width: 100%;
text-align: center;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%); i {
font-size: 28px;
color: #999;
} .ant-upload-text {
margin-top: 8px;
font-size: 12px;
color: #666;
}
}

Step3:添加事件处理

对上传图片的类型、大小和分辨率进行检测

<input
type="file"
id='file'
accept="image/jpeg, image/gif, image/png, image/bmp"
styleName="input-file"
onChange={e => {
this.onFileChange(e);
}}
/>
<label htmlFor="file" styleName="ant-upload">
{uploadButton}
</label>
</div> // 一些常量定义
const IMAGE_MIN_WIDTH = 1280; // 上传图片最小宽
const IMAGE_MIN_HEIGHT = 800; // 上传图片最小高
const IMAGE_MAX_SIZE = 1024 * 1024; // 上传图片最大大小 // 处理上传文件
onFileChange(e) {
const file = e.target.files[0];
e.target.value = ''; // 再次上传同一文件进行裁剪
if (this.handleBeforeUpload(file)) {
const reader = new FileReader();
reader.onload = e => {
const src = e.target.result;
const image = new Image();
const _this = this;
image.onload = () => {
const width = image.width;
const height = image.height;
if (width >= IMAGE_MIN_WIDTH && height >= IMAGE_MIN_HEIGHT) {
_this.setState({
initialImageUrl: src,
showCropModal: true
});
} else {
message.error('照片分辨率小于1280*800');
}
};
image.src = src;
};
reader.readAsDataURL(file);
}
} // 检查照片格式、大小等信息
handleBeforeUpload(file) {
if (file) {
const sizeOk = file.size < IMAGE_MAX_SIZE;
const typeReg = new RegExp(/^image\/bmp|gif|jpg|jpeg|png$/, 'i');
const typeOk = typeReg.test(file.type); if (!typeOk) {
message.error('照片格式有误');
} else if (!sizeOk) {
message.error('照片大小超过1M');
} return sizeOk && typeOk;
}
}

Step4:裁剪功能

代码较多就不展示了= =,使用的是react-cropper

Step5:预览和删除功能

预览功能实现思路就是通过判断是否已经上传图片来展示不同的状态。未上传展示uploadButton组件,已上传就展示imagePreview组件。
通过判断是否已经上传图片来控制input标签的id属性值,未上传图id='file',已上传图片将id='',这样一来,再次去点击label的时候由于for属性找不到对应的id,就不会触发input上onChange事件

<div>
<input
type="file"
id={imageUrl ? '' : 'file'}
accept="image/jpeg, image/gif, image/png, image/bmp"
styleName="input-file"
onChange={e => {
this.onFileChange(e);
}}
/>
<label htmlFor="file" styleName="ant-upload">
{imageUrl ? imagePreview : uploadButton}
</label>
</div>
<Modal
visible={showPreviewModal}
title="图片预览"
footer={null}
width={700}
onCancel={this.handlePreviewCancel}>
<img alt="" style={{ width: '100%' }} src={imageUrl} />
</Modal>
// imagePreview组件代码如下
const imagePreview = (
<div
styleName="image-background-preview"
style={{ backgroundImage: `url(${imageUrl})` }}>
<div styleName="preview-image">
<span styleName="preview-image-btn">
<a title="预览图片" href="javascript:;">
<Icon
type="eye"
styleName="icon-btn"
onClick={this.handlePreview}
/>
</a>
<a title="删除图片" href="javascript:;">
<Icon
type="delete"
styleName="icon-btn"
onClick={this.swapImageFile}
/>
</a>
</span>
</div>
</div>
); // 预览图片
handlePreview() {
this.setState({
showPreviewModal: true
});
} // 删除图片
swapImageFile() {
this.setState({ imageUrl: '' });
}

写在最后:项目涉及代码较多,文章只展示了大部分代码,一些具体细节代码可能就没有展示了,还望见谅,第一次写文章,可能比较混乱,有问题还望大家指出~~~ ^_^

自定义input上传图片组件的更多相关文章

  1. Vue组件之自定义表单组件

    今天又看了一遍vue的文档,记得之前学习的时候,官方文档中有提过,v-model指令是一个语法糖,做两件事,一个是给表单控件元素绑定value,第二个是当输入时更新绑定的值,不过后来在"表单 ...

  2. 自定义Vue&Element组件,实现用户选择和显示

    在我们很多前端业务开发中,往往为了方便,都需要自定义一些用户组件,一个是减少单一页面的代码,提高维护效率:二个也是方便重用.本篇随笔介绍在任务管理操作中,使用自定义Vue&Element组件, ...

  3. svelte组件:Svelte3自定义Navbar+Tabbr组件|svelte自定义插件

    基于Svelte3自定义组件Navbar+Tabbar沉浸式导航条|底部凸起菜单栏 Svelte 一种全新的构建用户界面的框架.当下热门的 Vue 和 React 在浏览器中需要做大量的工作,而 Sv ...

  4. iOS开发之自定义表情键盘(组件封装与自动布局)

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...

  5. BizTalk动手实验(十一)自定义开发管道组件

    1 课程简介 通过本课程熟悉自定义开始管道组件的流程.各组件接口的功能作用以及自定义管道. 本场景为开发一个消息ZIP压缩的发送管道组件. 2 准备工作 1. 熟悉管道组件各阶段组成 2. 下载Ion ...

  6. 自定义input file样式

    自定义input file样式:一般都是通过隐藏input,通过定义label来实现.这种做法要注意的是label的for属性要指定input对应的id; <!DOCTYPE html> ...

  7. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  8. 自定义vue全局组件use使用、vuex的使用

    自定义vue全局组件use使用(解释vue.use()的原理)我们在前面学习到是用别人的组件:Vue.use(VueRouter).Vue.use(Mint)等等.其实使用的这些都是全剧组件,这里我们 ...

  9. 百度小程序自定义通用toast组件

    百度小程序Toast组件 author: @TiffanysBear 百度小程序自定义通用toast组件 BdToast百度小程序自定义通用组件-github地址 需求 手百小程序的toast仅支持在 ...

随机推荐

  1. 360度3D 旋转插件

    Circlr插件是一款基于jQuery的可以对图片进行360度全方位旋转展示的插件.Circlr通过按一定角度规律拍摄的产品图片,制作出可以使用鼠标拖动.鼠标滚轮和移动触摸来进行图片逐帧旋转的效果.比 ...

  2. QQ音乐爬虫

    #今日目标 **QQ音乐爬虫** 今天要爬取的是QQ音乐任意歌手的所有音乐歌词,因为笔者是周杰伦的忠实粉丝,所以专门写了个爬虫来爬取他的音乐的歌词,因为他的音乐在咪咕音乐可以听,所以便没有去爬取. 好 ...

  3. aop设计原理(转)

    本文摘自 博文--<Spring设计思想>AOP设计基本原理 0.前言 Spring 提供了AOP(Aspect Oriented Programming) 的支持, 那么,什么是AOP呢 ...

  4. vue 实践技巧合集

    前言 本文纯属个人平时实践过程中的一些经验总结,算是一点点小技巧吧,不是多么高明的技术,如果对你有帮助,那么不胜荣幸. 本文不涉及罕见API使用方法等,大部分内容都是基于对vue的一些实践而已.由于涉 ...

  5. MySQL数据库入门常用基础命令

    MySQL数据库入门———常用基础命令      数据——公司的生命线,因此在大多数的互联网公司,都在使用开源的数据库产品,MySQL也因此关注度与使用率非常的高,所以做为运维的屌丝们,掌握它的一些基 ...

  6. 使用vue-cli脚手架快速构建项目

    1.创建一个文件夹,vscode打开 2.ctr + shift+` 打开指令窗口 3.npm i vue-cli -g   安装vue-cli 4.vue -V 测试安装版本 检查是否安装成功 5. ...

  7. ajax跨域jsonp —— javascript

    目录 jsonp是什么 jsonp原理 原生js使用jsonp jquery使用jsonp jsonp是什么 jsonp作用:解决跨域问题 为什么有跨域问题? “同源策略限制了从同一个源加载的文档或脚 ...

  8. 2019-11-29-C#-标准性能测试高级用法

    title author date CreateTime categories C# 标准性能测试高级用法 lindexi 2019-11-29 10:13:16 +0800 2018-07-08 0 ...

  9. SpringBoot打包成jar运行脚本

    #!/bin/bash #这里可替换为你自己的执行程序,其他代码无需更改 APP_NAME=csadmin.jar #使用说明,用来提示输入参数 usage(){ echo "Usage: ...

  10. 四、Vue CLI-异步请求(axios)

    一.模块的安装 npm install axios --save #--save可以不用写 如图: 二.配置main.js import axios from 'axios' Vue.prototyp ...