上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等。至于为何要把上传组件封装成一个公共的、可复用的组件,在前两篇文章封装react antd的form表单组件封装react antd的表格table组件中已经作了很多介绍,这里同样不再赘述。

有朋友觉得这些功能组件在各种前端框架满天飞的今天都大同小异、大差不差,甚至觉得Level有点Low。哈哈,其实事实也确实是这样的,我们去二次封装这些原本已基本成熟的框架组件,逼格也确实不高,且随心所欲的空间也不大,但我觉得这并不妨碍我们的日常开发。我们作为前端er,大部分工作都是在产品er的需求阴影下,顶着发际线越来越高的蒙圈脑袋,认认真真的砌墙,在胆战心惊、如履薄冰地试探下“今晚会否加班”的心态中活过每一个白天,已经是阿弥陀佛了。如果再碰上一个好的领导,在每一个阶段的开发任务结束后能再请我们去嗨皮一番,那就真是“今天好天气,老狼请吃鸡了。” 所以,我们能做的,只有简化开发步骤,提高组件的复用率,再完美一点就是提供可定制化的封装组件了。但这是个仁者见仁智者见智的看法,我还是很尊重认可有独立思考能力的人!

话不多说,先来介绍一下封装过程中所关注的几个点:

  • 上传文件大小

上传文件大小,势必需要我们去关注所上传文件的大小,这个功能点,我们放在antd所提供的upload组件的beforeUpload方法中,当然beforeUpload方法我们也是封装在upload组件中,通过使用时传入的配置来控制文件大小。

  • 上传文件的格式或类型

上传文件的格式或类型也是我们必须要去关注的一个点,比如这个上传控件只能上传图片,那个上传控件只能上传excel文档等等,我们可以使用antd所提供的upload组件的accept来控制,当然accept也是被封装在了upload组件中。

  • 自定义上传的方法

antd所提供的upload组件中给我们提供了一个action的API,官方的解释是action:上传的地址,跟form的表单提交有点类似,这种的上传方式我们不太好控制,我们会使用upload组件的customRequest方法来自定义上传的形式,官方对其的解释是:通过覆盖默认的上传行为,可以自定义自己的上传实现。

关于上传功能,我们需要注意的也基本就是以上三点,至于我们是上传到自己的服务器还是第三方如阿里云,则不在这篇文章的介绍范围了。下面来看一下具体实现。

外甥打灯笼——照舅(照旧)先放一张效果图:



效果图有点小,因为是缩略图,就不要介意这个细节了。

1、所封装的上传组件upload.js

import { createElement } from 'react'
import { Upload, message } from 'antd'; const h = createElement; const SUFFIX = /.+(\.\w+)$/,
BYTE = 1024,
ACCEPT = {
zip: 'application/zip,application/x-zip,application/x-zip-compressed',
pdf: 'application/pdf',
excel: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
image: 'image/jpeg,image/bmp,image/png,image/gif',
},
getAccepts = accept => (Array.isArray(accept) ? accept : [accept]).map(ac => ACCEPT[ac]).join(','),
beforeCheck = (config, file) => {
let { accept, max = Number.MAX_VALUE } = config || {}, { size, type } = file, accepts = getAccepts(accept).split(',');
//大小限制(M)
if(Math.pow(BYTE, 2) * max < size){
message.info(`文件不能超过${max}M`);
return false;
}
} const UploadComponent = props => {
let { children, config } = props, { accept } = config, attrs = {};
//不能在props对象上直接添加属性,只能再定义一个attrs对象
Object.assign(attrs, {
action: '',
accept: getAccepts(accept),
beforeUpload: file => beforeCheck(config, file),
customRequest: opts => {
let { file, onSuccess, onProgress, onError } = opts, { uid, name, type } = file;
name = `${uid}${name.replace(SUFFIX, '$1')}`;
//判断上传的文件是否是图片,若不是图片,前端可自行根据isImg来控制是否可预览文件
if(getAccepts(accept).indexOf(type) > -1) file.isImg = true // fetch('https://jsonplaceholder.typicode.com/posts', {
// method: 'POST',
// body: file,
// }).then(r => {
// let { res: { requestUrls } } = r;
// requestUrls = requestUrls.length < 1 ? '' : requestUrls[0]
// if (requestUrls.indexOf('?') > -1) requestUrls = requestUrls.split('?')[0]
// onSuccess({ res: file, url: requestUrls });
// }) let resFile = {
uid,
name,
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
} onSuccess(resFile)
},
}) return h(Upload, {...props, ...attrs}, children)
} export default UploadComponent

代码中注释的部分模拟的就是上传到服务器,不过这个地址是从antd上抄来的,貌似不能用。_

2、upload组件的使用方法:

import React, { useState } from 'react'
import Upload from './Upload' const UploadComp = () => {
const config = {
accept: 'image', //接受上传的文件类型:zip、pdf、excel、image,也可以是文件类型所组成的数组类型如:['image', 'pdf'],则只可以上传图片或pdf类型的文件,也可以为空,则任何类型的文件都可以上传
max: 1, //限制上传文件大小
}; const [fileList, setFileList] = useState([]) const onPreview = file => {
console.log(file)
} const onSuccess = res => {
//useState不能向数组中push数据,只能通过这样的方式来push数据
setFileList([...fileList, res])
} return <Upload listType="picture-card" config={config} fileList={fileList} onSuccess={onSuccess} onPreview={onPreview}>{fileList.length >= 2 ? null : '上传'}</Upload>
} export default UploadComp

最后还是再贴一下本次封装所用到的各个包的版本:

react: 16.8.6,

react-dom: 16.8.6,

react-router-dom: 5.0.0,

antd: 4.3.5,

@babel/core: 7.4.4,

babel-loader: 8.0.5

封装react antd的upload上传组件的更多相关文章

  1. 封装Vue Element的upload上传组件

    本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢.卧槽你妈,当场就把我吓了一 ...

  2. element-ui upload上传组件问题记录

    element-ui upload上传组件遇到的问题

  3. 封装react antd的form表单组件

    form表单在我们日常的开发过程中被使用到的概率还是很大的,比如包含了登录.注册.修改个人信息.新增修改业务数据等的公司内部管理系统.而在使用时这些表单的样式如高度.上下边距.边框.圆角.阴影.高亮等 ...

  4. 页面中使用多个element-ui upload上传组件时绑定对应元素

    elemet-ui里提供的upload文件上传组件,功能很强大,能满足单独使用的需求,但是有时候会存在多次复用上传组件的需求,如下图的样子,这时候就出现了问题,页面上有多个上传组件时,要怎么操作呢? ...

  5. element-ui Upload 上传组件源码分析整理笔记(十四)

    简单写了部分注释,upload-dragger.vue(拖拽上传时显示此组件).upload-list.vue(已上传文件列表)源码暂未添加多少注释,等有空再补充,先记下来... index.vue ...

  6. React+Antd+Antd-Img-Crop实现上传固定大小的裁剪头像或者图片(且可控制图片数量)

    见章知著 1024,程序员们节日快乐!本文主要讲述react配合antd以及react-img-crop第三方库实现一个可控的图片上传功能. 运行项目 需要具有node环境 第三方库安装 1.antd ...

  7. 在vue项目中使用element-ui的Upload上传组件

    <el-upload v-else class='ensure ensureButt' :action="importFileUrl" :data="upLoadD ...

  8. 使用Element的upload上传组件,不使用action属性上传

    1.需要实现的效果如下图,在点击提交的时候再提交file数据,和其他数据统一上传,我把file转换成了base64的格式,可以再上传之前显示缩略图 2.代码分析 action属性值为"#&q ...

  9. 国外十个出名的 upload 上传组件

    在日常开发中,我们常会用到很多的组件及共用代码提高我们的开发效率.   King MEDIA - $ 17.00 / 11 Sales DNNStore | 6/5/2014 6:06:42 PM|  ...

随机推荐

  1. Springboot启动扩展点超详细总结,再也不怕面试官问了

    1.背景 Spring的核心思想就是容器,当容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片.Springboot更是封装了Spring,遵循约定大于配置,加上自动装配 ...

  2. DP学习记录Ⅰ

    DP学习记录Ⅱ 前言 状态定义,转移方程,边界处理,这三部分想好了,就问题不大了.重点在状态定义,转移方程是基于状态定义的,边界处理是方便转移方程的开始的.因此最好先在纸上写出自己状态的意义,越详细越 ...

  3. java并发编程[持续更新]

    目录 java并发编程 1.常用类介绍 Semaphore 2.名词解释 2.1 线程安全 2.2 可重入锁和不可重入锁 java并发编程 1.常用类介绍 Semaphore Semaphore 类是 ...

  4. 一款直击痛点的优秀http框架,让我超高效率完成了和第三方接口的对接

    1.背景 因为业务关系,要和许多不同第三方公司进行对接.这些服务商都提供基于http的api.但是每家公司提供api具体细节差别很大.有的基于RESTFUL规范,有的基于传统的http规范:有的需要在 ...

  5. 微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示

    一.前言 项目中遇到的评分相关的需求其实还挺多.之前也写过网页中关于评分功能实现的文档.这次,是基于微信小程序开发而提炼出一个简单方便使用的方法,网页开发中同样可用.这次使用的还是字体,主要是字体这个 ...

  6. C语言中对文件的读写的一些浅显理解

    前述:基于上学期完成的数据结构的课程设计,对于老师的提出要求实现的基础上,自己在使用过程中发现每次打开程序都需要重新输入数据,于是便决定,将文件读写功能加入此次课程设计中,以下是我的一些心得和浅显理解 ...

  7. CSRF与XSS攻击的原理与防范

    CSRF 1.概念与原理 CSRF,跨站请求伪造,攻击方伪装用户身份发送请求从而窃取信息或者破坏系统.例如: 用户访问A网站登陆并生成了cookie,再访问B网站,如果A网站存在CSRF漏洞,此时B网 ...

  8. 学习python的几个资料网站

    菜鸟教程 https://www.runoob.com/python3/python3-tutorial.html https://www.runoob.com/python/python-tutor ...

  9. Python日期和时间_什么是Tick_什么是时间元组_获取当前时间

    Python 日期和时间_什么是 Tick _什么是时间元组: 时间和日期:某年某月某日某时某分某秒 Tick: 时间间隔以 秒 为单位的浮点小数,起始时间为:1970年1月1日0点0分开始 # Ti ...

  10. 什么是 PHP SimpleXML?

    PHP SimpleXML PHP SimpleXML 处理最普通的 XML 任务,其余的任务则交由其它扩展处理. 什么是 PHP SimpleXML? SimpleXML 是 PHP 5 中的新特性 ...