乐趣区

关于react.js:基于业务沉淀组件-managetable

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-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;

成果如下:

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

参数名 类型 阐明
name string 存储所应用的惟一的 key,必传
columns ManageColumnType[] GroupManageColumn[] 列数据,必传
ref React.createRef()的返回对象 减少面板,非必传
SettingComp React.ReactNode 自定义设置头部,非必传
setTitle React.ReactNode、string 自定义弹窗的题目,默认 ’ 设置显示字段 ’,非必传
defaultShowKeys string[] 默认显示的字段,不须要进行抉择 or 排序
initialShowKeys string[] 初始显示的字段,自定义存储
onKeysSelected (keys: string[]) => void 存储钩子函数,搭配自定义存储应用

ManageColumnType,继承自 antd 的 Table 的 ColumnType

参数名 类型 阐明
show boolean 是否默认显示

GroupManageColumn,继承自 antd 的 Table 的 ColumnType

参数名 类型 阐明
title string 组名,必传
records ManageColumnType[] 列数据,必传

写在最初

欢送应用和提交反馈。

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

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

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

退出移动版