本文已参与「 新人创作礼 」活动,一起开启掘金创作之路
一切的调研还是来源于业务的需求。
之前我说过了我最近构建一个新的前端工程。里面复用的都是公司历史自建的组建。
今天我调研的就是一个表单组建。
1.满足于UIUE的试图化需求。
我先说下,我需要哪些功能,然后我是怎么选择组件化的。
1)宽度在一定的容器100%撑开的。
2)高度是根据这个表单上面有个宽度100%的容器。这个容器高度是上下伸缩的,也就是支持resize: vertical;
3)支持列排序
4)支持title自定义Css
5)支持cell 自定义样式
6)扩展功能:支持operation操作表单 ( 增删按钮 )
7)容器需要flex:auto
-
只要支持over、黑白保护模式
-
分页、空内容等样式 ... 其他
这些知识我目前可以预测到的内容。当然可以自己造轮子,其实只是时间的问题。但是如何保证在业务满足的情况下,进行快速交付。
造轮子一定是没有办法妥协的情况下,然后申请去造一个table的轮子。
对于table组建,只要UI框架的都是被做过N次,不算新鲜了。就算造出来,也没有太多的成就感。
那对于这样的一个需求,如何去选择一个开源好用的框架呢 ? 还是需要有一定的技巧的。
从我个人的偏好,我首选肯定大公司、持续维护的表单组建。
看过我之前的文章,知道我目前搭建的项目技术框架选型。
React、Nextjs、styled-components、useContext、React-query 、i18n等搭建的一套技术框架方案
当然我选择第一我直接就是去github搜索热度最高的table组建。
按照惯例当然首选react-table。
经过几番筛查我确定也就这3个挑选其一。
react-bootstrap-table
react-table
ali-react-table
这几个其实是我已经调研的, 论稳定性、强大行、扩展性。我都应该选react-bootstrap-table。但是最后我放弃了。
先说说他的优点,历史悠久、api丰富、文档强大。
文档地址:ADDRESS 强大到你想哭,基本我想要的功能,在这些demo里面都覆盖了。但是我最后放弃了,他的css独立引用bootsrap的集成、用它会依赖一堆周边,他没法跟我的theme完美整合。需要我去定义一套欺负构建,他的亮点在功能交付上,对css的整合的未必满足我需求,当然也是可以用的。
react-table 是目前,可能是将来最为流行的表单框架。为啥我对他放弃。他也是一样,对于逻辑功能他能够他的hook强大到无与伦比。但是缺点显而易见,他想做的东西太多了,早起对CSS的貌似也是并不在意,他更关注扩展性跟逻辑交互。这也势必造成了摊子过大,后期被废弃的方案可能够多。
从这个地址就可以看到:他已经做的跟未做的:github.com/TanStack/re…
他的文档也是真的做的非常好,也是目前table 规模做的最大的一个组件化。( 开发中... )
在github上,他们还推荐了, React Query, React Form, React Charts 。貌似就是一批人做的,缺失做的非常好,React Query 我也是刚看的,但是我觉得业务考虑深度,已经让你足以成为一个废人。( 没有经历过这些业务痛点,在你用来可能不会有这样的感受 )
最后我选择的是ali-react-table , 按照我的性格,其实我最早就应该放弃这个,国产的轮子其实我一般好感度不高。这个不是针对,很多事KPI项目。不是说技术不行, 知识持续的维护性、技术文档看起来太参差不齐了。
ali-react-table其实文档在我啃下来我也碰到同样的问题。如果你只看文档, 估计在我上面要覆盖到的问题你也早就放弃了。
他共有2套文档:ali-react-table.js.org/docs/ ( 建议看这个 + 阅读部分demo源码 )github地址:github.com/alibaba/ali… 这个一看就知道是阿里的同学写的,对于阿里的同学的文档, 确实诟病太多,虽然我自己也是阿里系出来的,但是对于如何写好文档,缺失需要好好思考,当然阿里也是除了很多牛逼的前端开源,毕竟react的开源阿里是顶住半边天 ( antd、charts 、还有一些非常好用小工具,其实很多也是没有文档 )。Umi-React 应用开发框架、Dumi-组件/文档研发工具、qiankun-微前端框架、ahooks-React Hooks 库、Ant Motion-设计动效,还有牛逼的Egg。
课外话说多了,技术我谈谈ali-react-table。
我直接贴代码,毕竟都是八股文教科书,没啥难度,照着画。
import { BaseTable, features, useTablePipeline } from 'ali-react-table';
import styled from 'styled-components';
这2个包是必须要倒入的,这个css不需要你额外倒入,因为ali-react-table 在掘金发过一篇文章。
ali-react-table (github.com/alibaba/ali…)是我们小组开发的高性能 React 表格组件,我们在一开始就考虑了表格的性能,为其添加了内置的虚拟滚动特性。虚拟滚动会在数据量较大时自动开启,轻松展示一万行/一万列以上的数据。虚拟滚动是表格的核心特性之一,在为表格实现新功能时,我们会确保新功能不与虚拟滚动冲突。
作者:方凳雅集
链接:juejin.cn/post/687774…
虽然貌似很久没有维护了,但正是这篇文章,让我决定用这个。
当然还有一段话:ali-react-table 的主要定位是提供高性能、高可定制性的 React 表格,方便上层进行封装和定制并接入到不同的系统和业务中。ali-react-table 没有绑定特定的 React 组件库,仅依赖了一些工具类库(例如 rxjs、styled-components、classnames),配合 webpack/rollup 的 tree shaking 特性,引入 ali-react-table 所产生的额外 JS 体积非常有限。
阿里的东西,其实在业务场景的细腻度我觉得做的还是非常的不错。
继续看代码,以及我在文档无法得到解决的一个问题,其实应该非常简单,也简单。
const DarkSupportBaseTable: any = styled(BaseTable)`
--color: #333;
--row-height: 45px;
/* --line-height:45px; */
/* --cell-border: none; */
/* --cell-border-horizontal:none; */
--header-row-height: 45px;
--header-cell-border: none;
--cell-border-vertical: none;
/* width:100%; */
&.dark {
/* --bgcolor: #333;
--header-bgcolor: #45494f;
--hover-bgcolor: #46484a;
--header-hover-bgcolor: #606164;
--highlight-bgcolor: #191a1b;
--header-highlight-bgcolor: #191a1b;
--color: #dadde1;
--header-color: #dadde1;
--lock-shadow: rgb(37 37 37 / 0.5) 0 0 6px 2px;
--border-color: #3c4045; */
}
`;
这个代码是他定义csstoken,用来做皮肤设定。真的还是非常不错,因为他足够独一,我完全可以跟我项目中国呢主题完美结合起来。
const dataSource = [
{ prov: '湖北省', confirmed: 54406, cured: 4793, dead: 1457, t: '2020-02-15 19:52:02' },
{ prov: '广东省', confirmed: 1294, cured: 409, dead: 2, t: '2020-02-15 19:52:02' },
{ prov: '河南省', confirmed: 1212, cured: 390, dead: 13, t: '2020-02-15 19:52:02' },
{ prov: '浙江省', confirmed: 1162, cured: 428, dead: 0, t: '2020-02-15 19:52:02' },
{
prov: '湖南省',
confirmed: 1001,
cured: 417,
dead: 2,
t: '2020-02-15 19:52:02',
},
];
const columns = [
{ code: 'prov', name: '省份', width: 100, align: 'left' },
{ code: 'confirmed', name: '确诊', width: 100, align: 'right', features: { sortable: true } },
{ code: 'cured', name: '治愈', width: 100, align: 'right', features: { sortable: true } },
{
code: 'dead',
name: '死亡',
width: 100,
align: 'right',
headerCellProps: {
style: { color: 'white', fontSize: 12, background: '#1ea7fd' },
},
getCellProps(value: any, record: any) {
if (record.prov === '湖南省') {
return { style: { background: '#129835', color: 'white', fontWeight: 'bold' } };
}
},
},
{ code: 't', name: '最后更新时间', width: 180, align: 'right' },
// { lock: true, name: '操作', width: 200,render : function (a , b){
// console.log (a , b)
// return (<div>
// 编辑
// </div>)
// } },
];
这个也是所有表单组建需要 data、column。
这里的代码有排序,有表头Cell、cellProps的设置。已经列的锁定,已经自定义文本内容事件。
function getRowProps(record, rowIndex) {
return {
// style:
// rowIndex === 2
// ? {
// outlineOffset: -2,
// outline: '2px solid gold',
// '--hover-bgcolor': 'transparent',
// background: 'linear-gradient(140deg, #ff000038, #009cff3d)'
// }
// : {
// // 覆盖 website 中自带的 style,实际使用时可以忽略
// backgroundColor: 'transparent'
// },
// onClick() {
// alert(rowIndex);
// }
};
}
针对于行的样式处理。
const pipeline = useTablePipeline()
.input({ dataSource, columns })
.primaryKey('prov')
.use(features.sort({ mode: 'single', highlightColumnWhenActive: false })); //multiple
这个是对table灌数据、主键、feature功能的设定。上面的文档有针对于这个详细的文档介绍。
<DarkSupportBaseTable
{...pipeline.getProps()}
// getRowProps={getRowProps}
className="dark"
style={{}}
components={{ EmptyContent: () => <h1>数据为空~~</h1> }}
/>
这个其实有数据主任,以及模式的调用, 空数据组建展示的样子。
还有这个文档地址:shinima.github.io/ali-react-t… 建议大家就不要去过分认真,但是参考下,思考下当初作者为啥这么设计也是很有必要。
我当初了通过文档有一个点没有看到就是,如何自定义列。大致我可以猜测到差不多,最后还是通过在源码搜索关键字找到,才解决。
PS:这篇文行其实我要讲的是,不过过分纠结于技术选择,目标是解决问题, 且具有可持续,如果将来我们的table业务复杂到这个组建无法使用,也会考虑到重新造一个轮子也是不一定的。但是目前来说,拿来主义永远是最香的。