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 的展现,同时还可能定制展现列。那咱们就能够列一下需要了:
- 不影响 Table 的展现
- 能够抉择自定义展现列
- 能够对展现列进行排序
- 不会对业务产生其余影响(这是最次要的)
需要既然曾经明确,咱们就能够开整了,具体的实现,就不多说了,咱们能够看下实现后的成果:
打磨
既然曾经实现了最后的需要,就能够居安思危了。怎么可能呢?想太多了吧!!!
是的,起初产品说,当初数据展现列太多了,比之前多了三倍,想在对展现列进行抉择的时候进行一下分组,不然都挤在一块稀稀拉拉的不好找,重大影响工作效率了!
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
团队
TNTWeb – 腾讯新闻前端团队,TNTWeb 致力于行业前沿技术摸索和团队成员集体能力晋升。为前端开发人员整顿出了小程序以及 web 前端技术畛域的最新优质内容,每周更新 ✨,欢送 star,github 地址:https://github.com/tnfe/TNT-Weekly