基于业务沉淀组件 manage-table

模式冰川
• 阅读 2507
2020年下半年,有几张图片刷屏:有人骑在自行车上看书,有人边骑车边用电脑,有人床上铺满了一摞摞书……“边骑车边用电脑”的同学被称为“卷王”登上热搜。
慢慢的这些同学毕业了,卷王带着卷走上了社会,带动了其他人一起卷,卷的人越来越多了,苦不堪言,就导致了一些重复造轮子和造一些毫无意义的轮子的现象出现。

造轮子,本来是件好事,但是随着内卷的出现,造轮子就慢慢演变成了一个极端,出现了凭空造轮子和重复造轮子的事情,既不能服务于业务,还使得内卷现象越来越严重,真正的苦不堪言。

分析当前业务遇到的问题,进而产生新的思路和总结,利用技术的手段提升工作效率,提高开发速度,才是真正的有意义的轮子,也不枉一场。

场景

CMS(content management system)一词出现已久,通常指的是内容管理系统,是一种位于WEB前端和后端办公系统或流程之间的软件系统。在开发cms后台的过程中,最最常用的应该就是Table了,例如 antd的table:

基于业务沉淀组件 manage-table
这应该是最最常用的开发后台管理系统中使用到的组件了,没有个Table,都不好意思说是个cms系统。不过在稍微庞大的业务中会存在一个非常常见的问题,就是一个数据源会有很多很多字段需要进行展示,如果都展示出来呢,就会存在一个非常不美观且乱糟糟的感觉,眼花缭乱。同时不同的人,希望看到的字段也是不一样的,比如A同学希望看到标题0、1、2、3,B同学希望看到标题1、2、3、4,C同学希望看到标题7、8、9、10等。

这样就是一个非常个性化的需求了,如果希望后端同学来参与的话,就会增加后端同学的工作量,同时前端工作也不会相应的减少。得益于浏览器的localstorage存储能力,前端就可以实现,根本不需要后端同学的参与。

实现

首先,既然是antd的Table组件,我们肯定是要基于现有的功能去实现这个需求,所以我们需要在Table组件的基础上套一层,既不能影响Table的展示,同时还能够定制展示列。那我们就可以列一下需求了:

  1. 不影响Table的展示
  2. 可以选择自定义展示列
  3. 可以对展示列进行排序
  4. 不会对业务产生其他影响(这是最主要的)

需求既然已经明确,我们就可以开整了,具体的实现,就不多说了,我们可以看下实现后的效果:

基于业务沉淀组件 manage-table

打磨

既然已经实现了最初的需求,就可以高枕无忧了。怎么可能呢?想太多了吧!!!

是的,后来产品说,现在数据展示列太多了,比之前多了三倍,想在对展示列进行选择的时候进行一下分组,不然都挤在一块密密麻麻的不好找,严重影响工作效率了

WTF!最见不得别人说影响工作效率了,这么严重的问题怎么现在才说,怎么不早点提需求过来呢?早点提过来肯定早就实现了啊,不会存在影响工作效率的问题啊.

啊!!!我可真是个口是心非的渣男,可是我知道,小蝌蚪才是渣男,我不配啊!!说多了都是泪啊,还是抓紧做需求吧。看下实现效果:

基于业务沉淀组件 manage-table
嗯,完美,就是这么个效果。对Table的封装进行了二次修改,在不影响之前的使用方式的基础上,增加了对分组的能力支持,我可真TM棒!

> 然而,快乐的时光总是那么短暂啊~~

有一天,我们的另外一个平台发现,咦,你这个功能还怪好用嘞,能不能给我们也用用,好吧,最简单直接的方式是复制粘贴呀。复制粘贴到一半的时候,突然又来了一个人也想用用这个功能,WTMD就很头大。

这么说来,还是封装成一个npm包吧,等我会,我给你们发布成一个组件包,你们直接安装使用即可。

npm i manage-table

尽管拿去用吧。

使用

安装

npm i manage-table
or
yarn add manage-table

manage-table组件有对应的peerDependencies,如果没有安装的话,需要手动安装一下对应的依赖:

"peerDependencies": {
  "@ant-design/icons": "^4.6.4",
  "antd": "^4.12.0",
  "react": "^17.0.0",
  "react-beautiful-dnd": "^13.1.0"
}

使用方式-: 直接引用,使用内置设置

代码如下:

import ManageTable  from "manage-table";
import './App.css';
import React from "react";

function App() {
  const mockColumns = new Array(50).fill('').map((_item: string, index) => {
    return {
      dataIndex: 'title' + index,
      key: 'title' + index,
      title: '标题' + index,
      show: index % 3 === 0,
    };
  });
  mockColumns.push({
    dataIndex: 'action',
    key: 'action',
    title: '操作',
    show: true,
  });
  return (
    <div className="App">
      <ManageTable name="testTable" columns={mockColumns}/>
    </div>
  );
}

export default App;

效果如下:

基于业务沉淀组件 manage-table

使用方式二:自定义header部分

代码如下:

import React from "react";
import { Button } from "antd";
import ManageTable from "manage-table";

export default function App2() {
  const mockColumns = new Array(50).fill("").map((_item, index) => {
    return {
      dataIndex: "title" + index,
      key: "title" + index,
      title: "标题" + index,
      show: index % 3 === 0
    };
  });
  mockColumns.push({
    dataIndex: "action",
    key: "action",
    title: "操作",
    show: true
  });
  const ref = React.createRef();
  const handleShowModal = () => {
    ref.current.showModal();
  };
  const SettingHeader = (
    <div style={{ textAlign: "left" }}>
      <Button onClick={handleShowModal}>自定义设置</Button>
    </div>
  );
  return (
    <div className="App">
      <ManageTable
        ref={ref}
        SettingComp={SettingHeader}
        name="testTable2"
        columns={mockColumns}
      />
    </div>
  );
}

效果如下:

基于业务沉淀组件 manage-table

使用方式三:分组展示

代码如下:

import React from "react";
import { Button } from "antd";
import ManageTable from "manage-table";

const mockGroup = () => {
  const data = new Array(4).fill('').map((_item:string, index: number) => {
    return {
      title: '分组' + index,
      records: new Array(10).fill('').map((_item: string, indx) => {
        return {
          dataIndex: 'title' + index + '_' + indx,
          key: 'title' + index + '_' + indx,
          title: '标题' + index + '_' + indx,
          show: indx % 5 === 0,
        };
      }),
    };
  });
  // 任何一个索引都可以,不必须是0
  data[0].records.push({
    dataIndex: 'action',
    key: 'action',
    title: '操作列',
    show: true,
  })
  return data;
}

export default function AppGroupRef() {
  const ref: any = React.createRef();

  const handleSet = () => {
    ref.current.showModal();
  }

  const SettingHeader = (
    <div style={{textAlign: 'left'}}>
      <Button type="primary" onClick={handleSet}>自定义设置</Button>
    </div>
  );
  return (
    <div className="App">
      <ManageTable ref={ref} SettingComp={SettingHeader} name="testTableGroup" columns={mockGroup()}/>
    </div>
  );
}

效果如下:

基于业务沉淀组件 manage-table

其他方式

除了可以上面三种方式使用之外,还支持固定展示的配置,即部分字段默认展示且不允许进行排序和删除。manage-table默认是存储在浏览器的缓存里面的,是跟随浏览器走的,如果不想走浏览器缓存,而是自定义存储的话,也是支持的。

具体如下:

ManageTable, 继承自antd的Table

参数名类型说明
namestring存储所使用的唯一的key,必传
columnsManageColumnType[]GroupManageColumn[]列数据, 必传
refReact.createRef()的返回对象增加面板, 非必传
SettingCompReact.ReactNode自定义设置头部, 非必传
setTitleReact.ReactNode、string自定义弹窗的标题,默认'设置显示字段', 非必传
defaultShowKeysstring[]默认显示的字段,不需要进行选择or 排序
initialShowKeysstring[]初始显示的字段,自定义存储
onKeysSelected(keys: string[]) => void存储钩子函数,搭配自定义存储使用

ManageColumnType, 继承自antd的Table的ColumnType

参数名类型说明
showboolean是否默认显示

GroupManageColumn, 继承自antd的Table的ColumnType

参数名类型说明
titlestring组名,必传
recordsManageColumnType[]列数据, 必传

写在最后

欢迎使用和提交反馈。

2022年了,让我们接着起来吧,停止瞎卷,开启优卷

马上放假了,提前祝大家新年快乐吧~

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
4年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这