「趣学前端」今日祝福不限量,批量导入在路上

简介: 用技术实现梦想,用梦想打开创意之门。今天分享批量导入在路上。

工作分享两不误

第四季度,突然就忙碌了起来,除了完成业务需求,不断实现自我能力提升,以及制定前端新的季度规划,还要关注团队成员的技术成长。所以我开始以我自己的领导为榜样(我领导人很睿智稳重,能力超级强),学习他处理问题的方法。感谢我领导,我可以不用摸着石头过河。

虽然日常事情比较多,但是有了好的想法或者功能,我还是忍不住想分享出来。因为我的同事对我的帮助也是温暖而细致的。(我的天使同事们,我的问题必然是完完全全,从实现到原理,都让我理解的通透了。)

这不最近的需求里有一个批量导入的功能,我翻了一下项目代码,大部分批量导入功能都是直接加到页面里的,没有做模块化处理,于是我结合对业务的理解以及未来可扩展的大致预测,把批量导入封装成为一个业务组件。


项目基于React框架开发的,所以代码写法是JSX语法,组件开发使用的hooks函数式组件,UI框架使用的是antd。


灵感源于快乐

把流水的业务需求,改变成主动的寻找开发灵感,每次有新的开发收获,我就会给自己一朵小红花,谁会嫌小红花多呢。

多个批量导入功能的流程

我梳理的流程图如下:

image.jpeg


组件封装

业务场景的思考

有时候同一个产品,对于相同的功能,设计成不同的交互。我们系统里的批量导入有两种,一种是弹窗交互的方式进行文件导入,一种是页面直接展示导入按钮组。

弹窗交互方式

image.jpeg

页面上直接展示导入按钮组

image.jpeg


上面无论哪种,选择文件功能和导入确定功能是一样的。但是交互方式不一样,前端进行布局处理也会不一样。所以我在产品同事评审需求的时候会提前沟通交互方式。另外对于公司内部的后台管理系统,我个人更倾向简约设计,相似功能不推荐交互方式做的五花八门。所以目前我们系统里的批量导入功能只有这两种交互方式。今天分享的是页面上直接操作上传导入的这种方式的业务功能组件化处理。


功能的可拓展

批量导入的功能相对简单,目前可拓展的有以下几个点

  • 导入按钮支持单个或者多个;
  • 下载模板按钮支持单个或者多个;
  • 支持多个导入只需要一个下载模板按钮的存在。


功能实现

  • 选择文件功能使用antd提供的上传组件;
  • 导入按钮使用的是数组对象,通过map方法直接循环渲染;
  • 根据产品的需求,导入和模板是分开的,所以前端布局也就分开, 不过数据和导入是同一个数组对象。
  • 正如上面流程图的设计,当页面存在多个导入按钮的时候,会进行按钮操作的控制。每个导入按钮设置了可操作开关,一次导入操作中只有一个按钮是可以操作的。
/** * @description 公共业务组件-批量上传 目前多个批量上传操作 */importReact, { useState, Fragment } from'react';
import { useHistory } from'react-router-dom';
importPropTypesfrom'prop-types';
import_from'lodash';
importaxiosfrom'axios';
import { Button, Row, Col, Upload, Space, message } from'antd';
import { UploadOutlined } from'@ant-design/icons';
importstylefrom'./style';
constCommonMultipleBatchImport= ({ ...props }) => {
const { importList, callback } =props;
consthistory=useHistory();
const [fileList, setFileList] =useState([]);
const [file, setFile] =useState(null);
const [importListInit, setImportListInit] =useState(_.cloneDeep(importList));
/**   * 上传前事件   * @param {Object} file 上传的文件对象   * @return {void} 无   */constbeforeUpload=file=> {
setFile(file);
setFileList([file]);
returnfalse;
  };
/**   * 上传事件   * @param {Object} item 当前操作的上传对象   * @return {void} 无   */constupload= (item, index) => {
if (!file) {
returnmessage.error('请选择文件');
    }
message.info('祝福上传中,请稍后');
letlist=_.cloneDeep(importListInit);
list.map((itm, inx) => {
// 上传操作项加载和不可点击的处理itm.loading=inx===index?true : false;
itm.disabled=true;
    });
setImportListInit(list);
constformData=newFormData();
formData.append('file', file);
axios      .post(item.httpMethod, formData, { nobody: true })
      .then(() => {
message.success('祝福批量导入成功,您的家人朋友不久便能收到~');
      })
      .finally(() => {
letlistFinally=_.cloneDeep(importListInit);
listFinally.map(itm=> {
itm.loading=false;
itm.disabled=false;
        });
setImportListInit(listFinally);
setFileList([]);
setFile(null);
callback&&callback(true);
      });
  };
/**   * 文件移除事件   * @param {void} 无   * @return {void} 无   */constonRemove= () => {
setFile(null);
setFileList([]);
  };
/**   * 下载模板   * @param {Object} item 当前操作的上传对象   * @return {void} 无   */constdownTemplate=item=> {
location.href=item.downUrl;
  };
return (
<Rowalign="middle"className={style['multiple-datch-import']}><ColclassName="file-col mr10"><Uploadaccept=".xlsx,.xls"onRemove={onRemove} fileList={fileList} beforeUpload={beforeUpload}><Buttonicon={<UploadOutlined/>}>选择文件</Button></Upload></Col><Colspan={6}><Space>          {/* 操作按钮 */}
          {importListInit.map((item, index) => {
return (
<Buttonkey={item.key} type="primary"onClick={() =>upload(item, index)} loading={item.loading} disabled={item.disabled||!file}>                {item.name}
</Button>            );
          })}
          {/* 下载模板 */}
          {importListInit.map(item=> {
return (
<Fragmentkey={item.key}>                {item.downUrl? (
<Buttontype="primary"onClick={() =>downTemplate(item)}>                    {item.downName}
</Button>                ) : null}
</Fragment>            );
          })}
</Space></Col></Row>  );
};
CommonMultipleBatchImport.propTypes= {
importList: PropTypes.array.isRequired, // 上传内容的数组对象callback: PropTypes.func, // 操作的回调};
CommonMultipleBatchImport.defaultProps= {
importList: [],
};
exportdefaultCommonMultipleBatchImport;


组件使用

组件引入

我们的业务组件都放到了/bundleComponents下,所以引入的时候也会找对应的文件位置。

list.jsx

// 组件引入import { CommonMultipleBatchImport } from'@/bundleComponents';
// 页面使用<CommonMultipleBatchImportcallback={listQuery} importList={importList} />


组件通信

props传参

  • 下载模板:值可以为空,当它的值为空时,页面不展示下载模板按钮;
  • 导入接口请求地址:我们的导入处理,是直接拿到文件流通过接口传给后端,后端再对文件数据做处理。不同的公司可能有不同的处理方式,此处可以根据实际情况重新处理。
// 导入 操作数组对象constimportList= [
  {
key: 'fuqi', // 导入 操作key值name: '批量导入福气', // 导入 操作按钮名称downName: '下载模版', // 下载模板按钮名称downUrl: '实际的下载模板链接', // 下载模板打开链接httpMethod: '实际的接口请求地址', // 导入接口请求地址  },
  {
key: 'zhufu',
name: '批量导入祝福',
downName: '下载删除模版',
downUrl: '', // 下载模板打开链接 值为空的按钮不展示httpMethod: '实际的接口请求地址',
  },
];


回调函数

因为数据导入成功之后需要更新当前页面,所以在导入成功的逻辑里做了回调处理,回调后会进行列表页面的刷新。

constlistQuery= () => {
list.query();
};


总结

批量导入的功能,不是很复杂,尤其把操作梳理清楚,每一种情况都模拟清楚,其实代码量是很少的。

重要的是,遇到相似的业务功能,可以先做功能设计,再敲代码。有些功能虽然展示内容不一样,但是流程和核心功能是一致的,就可以考虑功能模块化封装。这样的好处是,既能在业务开发中得到技术提升,又能提高效率,看似复杂的功能,其实我们早就做成组件了,页面直接引入使用,几行代码就能搞定。

目录
相关文章
|
数据采集 移动开发 前端开发
如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)
最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解决方案. 笔者将分成3篇文章来复盘, 主要解决场景如下
808 0
|
5月前
|
前端开发 JavaScript PHP
技术心得:前端点击按钮,导入excel文件,上传到后台,excel接收和更新数据
技术心得:前端点击按钮,导入excel文件,上传到后台,excel接收和更新数据
57 0
|
7月前
|
前端开发 JavaScript 搜索推荐
专业与传统相融,程序员特有祝福:通过前端代码送上新春祝福
新春佳节即将来临,忙了一年,作为程序员,当然要用属于程序员独有的方式来给大家送上新春祝福。在这个喜庆的时刻,让我们以技术的视角来送上一份特别的新春祝福,作为程序员,我们可以用代码和技术,为了大家带来一份独特而有趣的祝福,为了给节日增添一份属于技术人特有的魅力,以前端开发的视角来送上一份特别的新春祝福。作为前端开发者,通过编写前端代码可以创造出丰富多样的视觉效果,可以利用HTML、CSS和JavaScript等编写代码来呈现出直观的新春祝福效果,为大家呈现出生动直观的新春祝福。那么本文以前端程序员的视角,结合前端专业知识送上新春祝福,希望在新的一年里,大家的生活充满幸福和技术的收获。
88 1
专业与传统相融,程序员特有祝福:通过前端代码送上新春祝福
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
40 0
|
前端开发
前端学习笔记202305学习笔记第二十天-vue3.0-把element-ui组件导入封装为特定模块
前端学习笔记202305学习笔记第二十天-vue3.0-把element-ui组件导入封装为特定模块
71 0
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧1
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧1
62 0
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧3
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧3
50 0
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧3
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧3
48 0
|
前端开发
前端学习笔记202305学习笔记第二十四天-模块之require导入
前端学习笔记202305学习笔记第二十四天-模块之require导入
41 0
|
JavaScript 前端开发
web前端html写一个动态中秋明月!祝福大家中秋快乐!
中秋节,是我们国家的四大传统节日之一!中秋节有很多的别称,有祭月节、月光诞、月夕、秋节、仲秋节、拜月节等等,仲秋节源自于天象崇拜,有上古时代秋夕祭月演变而来。中华求解中秋节自古便有祭月、赏月、吃月饼、看花灯、赏桂花、饮桂花酒等民俗,流传至今,经久不息。
web前端html写一个动态中秋明月!祝福大家中秋快乐!