2

基于业务沉淀组件 => manage-table

 2 years ago
source link: https://segmentfault.com/a/1190000041436023
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

基于业务沉淀组件 => manage-table

基于业务沉淀组件 => manage-table

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

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

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

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

图片.png 这应该是最最常用的开发后台管理系统中使用到的组件了,没有个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. 不会对业务产生其他影响(这是最主要的)

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

图片.png

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

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

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

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

图片.png 嗯,完美,就是这么个效果。对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;
复制代码

效果如下:

图片.png

使用方式二:自定义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>
  );
}
复制代码

效果如下:

图片.png

使用方式三:分组展示

代码如下:

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>
  );
}
复制代码

效果如下:

图片.png

除了可以上面三种方式使用之外,还支持固定展示的配置,即部分字段默认展示且不允许进行排序和删除。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[]列数据, 必传

欢迎使用和提交反馈。

TNTWeb - 腾讯新闻前端团队,TNTWeb 致力于行业前沿技术探索和团队成员个人能力提升。为前端开发人员整理出了小程序以及 web 前端技术领域的最新优质内容,每周更新 ✨,欢迎 star,github 地址:https://github.com/tnfe/TNT-Weekly

image.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK