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

造轮子,原本是件坏事,然而随着内卷的呈现,造轮子就缓缓演变成了一个极其,呈现了凭空造轮子和反复造轮子的事件,既不能服务于业务,还使得内卷景象越来越重大,真正的苦不堪言。

剖析以后业务遇到的问题,进而产生新的思路和总结,利用技术的伎俩晋升工作效率,进步开发速度,才是真正的有意义的轮子,也不枉一场。

场景

CMS(content management system)一词呈现已久,通常指的是内容管理系统,是一种位于WEB前端和后端办公零碎或流程之间的软件系统。在开发cms后盾的过程中,最最罕用的应该就是Table了,例如 antd的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. 不会对业务产生其余影响(这是最次要的)

需要既然曾经明确,咱们就能够开整了,具体的实现,就不多说了,咱们能够看下实现后的成果:

打磨

既然曾经实现了最后的需要,就能够居安思危了。怎么可能呢?想太多了吧!!!

是的,起初产品说,当初数据展现列太多了,比之前多了三倍,想在对展现列进行抉择的时候进行一下分组,不然都挤在一块稀稀拉拉的不好找,重大影响工作效率了

WTF!最见不得他人说影响工作效率了,这么重大的问题怎么当初才说,怎么不早点提需要过去呢?早点提过来必定早就实现了啊,不会存在影响工作效率的问题啊.

啊!!!我可真是个口不应心的渣男,可是我晓得,小蝌蚪才是渣男,我不配啊!!说多了都是泪啊,还是放松做需要吧。看下实现成果:


嗯,完满,就是这么个成果。对Table的封装进行了二次批改,在不影响之前的应用形式的根底上,减少了对分组的能力反对,我可真TM棒!

> 然而,高兴的时光总是那么短暂啊~~

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

这么说来,还是封装成一个npm包吧,等我会,我给你们公布成一个组件包,你们间接装置应用即可。

npm i manage-table

只管拿去用吧。

应用

装置

npm i manage-tableoryarn 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;

成果如下:

应用形式二:自定义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>  );}

成果如下:

应用形式三:分组展现

代码如下:

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默认是存储在浏览器的缓存外面的,是追随浏览器走的,如果不想走浏览器缓存,而是自定义存储的话,也是反对的。

具体如下:

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[]列数据, 必传

写在最初

欢送应用和提交反馈。

  • 开源代码仓库:manage-table
  • npm 地址: manage-table

2022年了,让咱们接着起来吧,进行瞎卷,开启优卷

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