antd table设置表格一个单元格的字体颜色_alireacttable:高性能 React 表格组件

5b308ab540fcd7f00c50c51111ec5bf1.png

点击上方蓝字关注我们

简介

在前端开发中,表格一直都是最复杂的组件之一。表格不仅要支持丰富的操作(排序、过滤、搜索、分页、自定义列等),还要有非常好的性能以展示大量数据。很多组件库(例如 fusion design,ant design)提供了功能丰富的表格组件,这些表格一开始没有过多考虑性能问题,往往是后面遇到性能瓶颈问题时才考虑添加虚拟滚动特性,但此时过多的表格功能使得性能优化的难度非常高。

ali-react-table (https://github.com/alibaba/ali-react-table)是我们小组开发的高性能 React 表格组件,我们在一开始就考虑了表格的性能,为其添加了内置的虚拟滚动特性。虚拟滚动会在数据量较大时自动开启,轻松展示一万行/一万列以上的数据。虚拟滚动是表格的核心特性之一,在为表格实现新功能时,我们会确保新功能不与虚拟滚动冲突。

表格组件的基本用法和 antd/fusion 表格类似,传入 dataSource 来指定表格的数据源,传入 columns 来对表格的列进行配置。

import { BaseTable } from 'ali-react-table'function BasicUsage() {  const dataSource = [    { prov: '湖北省', confirm: 54406, cure: 4793, dead: 1457, t: '2020-02-15 19:52:02' },    { prov: '广东省', confirm: 1294, cure: 409, dead: 2, t: '2020-02-15 19:52:02' },    { prov: '河南省', confirm: 1212, cure: 390, dead: 13, t: '2020-02-15 19:52:02' },    { prov: '浙江省', confirm: 1162, cure: 428, dead: 0, t: '2020-02-15 19:52:02' },    { prov: '湖南省', confirm: 1001, cure: 417, dead: 2, t: '2020-02-15 19:52:02' },  ]  const columns = [    { code: 'prov', name: '省份', width: 150 },    { code: 'confirm', name: '确诊', width: 100, align: 'right' },    { code: 'cure', name: '治愈', width: 100, align: 'right' },    { code: 'dead', name: '死亡', width: 100, align: 'right' },    { code: 't', name: '更新时间', width: 180 },  ]  return <BaseTable dataSource={dataSource} columns={columns} />}

dd7df7299e5e40beabff7dea4f77b751.png

虚拟滚动

当数据量较大时,表格会自动开启虚拟滚动。

6bb928fe002b51162b49cdd0cfd8c5a9.gif

↑ 通过 dataSource 传入一个长度超过 5 万的数组,表格依旧流畅。当表格向下滚动时,BaseTable 默认会为表头设置 style.position=sticky,表头将会吸附在页面或滚动容器的顶部。

锁列与单元格合并

在维度、指标数量较多情况下,设置 column.lock=true 可以在表格左侧或右侧锁定指定的列,提升交互体验。

在更复杂的情况下,可以设置 column.getSpanRect 来指定单元格的合并情况;column.getSpanRect 返回每个单元格被合并之后的矩形位置,在渲染表格时,BaseTable 会根据单元格的位置和对应的 spanRect,来为单元格动态设置 rowSpan/colSpan,使得在虚拟滚动场景下合并单元格依然可以生效。

基于这些实用的表格特性,我们可以在表格上进行深度定制与二次开发,实现下钻、右键菜单、交叉表/透视表、收拢/展开等功能。同时表格内置的虚拟滚动保证了大数据量下表格仍具有很好的性能,上层使用者不需要担心性能问题。

下图是基于 BaseTable 的一个简单的透视表 demo(在线 demo[1]):

3bb6791c997eec4972c39b270271c99c.gif

表格功能拓展

BaseTable 是一个相对底层的 React 组件,仅提供了基本的表格渲染功能。为了方便对表格进行功能拓展,我们为 BaseTable 设计了一个简单的拓展方案,然后我们基于该方案实现了一些常见的表格功能,包括排序、树状模式、列高亮等。

我们知道 BaseTable  基于 dataSource 和 columns 来渲染表格,按照一定的规则对 dataSource/columns 进行包装和转换,可以改变 dataSource/columns 的值或渲染输出,实现特定的功能。

type Transform = (input: T) => Ttype TableTransform = Transform  columns: ArtTableColumn[]  dataSource: any[]}>

TableTransform(后面简称 transform)是一个纯函数,输入列配置 + 数据源,输出一份新的列配置 + 数据源。每一个 transform 通过对 dataSource/columns 的包装和转换以实现一个新的特性。注意到每个 transform 的输入和输出的类型相同,我们可以将多个 transform 串联以实现不同功能的组合。

ali-react-table/biz 提供了一些常见表格功能的 transform,下面以「排序和列高亮两个功能的组合」为例介绍 transform 的使用方式

6a4718f43a7a0274ab3942c82ed7ed90.gif

对应的代码如下:

import { ArtColumn, BaseTable } from 'ali-react-table'import { applyTransforms, commonTransforms } from 'ali-react-table/biz'import React, { useState } from 'react'function SingleSortExample() {  const { isLoading, dataSource } = useProvinceDataSource()  const columns = [    // 通过 features.sortable 来标记 可排序的列    { code: 'provinceName', name: '省份', features: { sortable: true } },    { code: 'confirmedCount', name: '确诊', features: { sortable: true } },    { code: 'curedCount', name: '治愈', features: { sortable: true } },    { code: 'deadCount', name: '死亡', features: { sortable: true } },    { code: 'updateTime', name: '最后更新时间' },  ]  // transform 都是纯函数,所需的额外状态需要上层提供,这里使用 useState 来快速创建状态  const [hoverColIndex, onChangeHoverColIndex] = useState(-1)  const [sorts, onChangeSorts] = useState([{ code: 'deadCount', order: 'desc' }])  const renderData = applyTransforms(    { columns, dataSource },    commonTransforms.columnHover({ hoverColIndex, onChangeHoverColIndex }),    // 设置 sort.mode=multiple 可以使用多列排序    commonTransforms.sort({ mode: 'single', sorts, onChangeSorts }),  )  // applyTransform 是使用多个 transform 的辅助函数  // 上面的代码相当于:  // input = { dataSource, columns }  // t1 = commonTransforms.columnHover(...)  // t2 = commonTransforms.sort(...)  // renderData = t2(t1(input))  return <BaseTable dataSource={renderData.dataSource} columns={renderData.columns} />}

相比于原来的「直接通过 props 设置表格配置」的方式,transform 使用起来更麻烦一些,但它的优势也非常明显:

  • 对于用户:

    • 按需引入 transform,多个 transform 可组合性较好,降低多个功能之间的冲突概率

    • 因为原来表格封装了所有功能,多个功能之间非常容易发生冲突

    • 表格功能不满足业务需求时,可自行实现自定义 transform,与 commonTransforms 配合使用

  • 对于表格组件维护者(也就是我):拓展功能所需的状态由上层提供,表格内部的状态数量可控,降低表格性能优化的难度,表格组件维护起来比较容易

同时这也带来了更清晰的表格功能设计分层:BaseTable 提供灵活的 column 配置来提供高可定制性,上层实现各类 transform 实现拓展功能。表格的基本功能由 ali-react-table 提供,而拓展功能则需要从 ali-react-table/biz 引入。 下表展示了 BaseTable 中列配置对象的结构,可以看到上层可以定制列标题、宽度、锁列、单元格等内容,几乎涵盖了列的每个方面。

d18bcd763742a8e3e6d0b1a18077dee1.png

ali-react-table/biz 还通过 commonTransform 提供了树状模式、自定义列、表格操作栏等功能,更多的功能也正在不断开发中,将通过统一的拓展方式进行提供。

45c50e1730ad062bc61bb898600eb39e.png

↑ 左:树状模式;右:自定义列

当遇到一些不常见的表格需求时,我们可以通过手动定制列的 render/getCellProps 来满足定制需求:

c20956b90dc8e081ee473d4a9b7a8722.png

交叉表

除了常见的行列数据,展示交叉数据或透视数据也是常见的表格需求。前述的 BaseTable 只能够展示行列异构的数据:行(dataSource)负责提供数据,列(columns)控制表格如何展现;而交叉/透视数据的行表头和列表头是同构的(行表头和列表头都是树状结构)。为了方便展示行列同构数据,我们基于 BaseTable  实现了一个简单的交叉表格(CrossTable),专门应对「行表头和列表头都是一棵树」 的场景。

ali-react-table/pivot 提供的交叉表(CrossTable)也是一个较为底层的 React 组件,仅提供表格结构的渲染能力。CrossTable 的渲染过程可认为是:左树 + 上树 => 表格。大致使用方式如下:

  // 推荐为交叉表设置一个默认列宽  defaultColumnWidth={100}  // leftTree, topTree 均为 { key, value, children } 的嵌套树状结构  leftTree={leftTree}  topTree={topTree}  getValue={(leftNode, topNode) => {    // 自定义的取数逻辑,针对每个单元格都会调用一次    // leftNode 表示当前单元格对应的左侧树节点,topNode 是对应的上方树节点  }}  render={(value, leftNode, topNode) => {    // 可选的 自定义的渲染逻辑    return value  }}/>

CrossTable 这里就不再过多介绍了,表格的效果可见本文上面透视表 demo 动图。ali-react-table/pivot 还提供了一些透视数据处理方法,方便在前端进行一些简单的数据聚合运算并将其展示到表格上,具体可见 相关文档[2]。

小结

ali-react-table 的主要定位是提供高性能、高可定制性的 React 表格,方便上层进行封装和定制并接入到不同的系统和业务中。ali-react-table 没有绑定特定的 React 组件库,仅依赖了一些工具类库(例如 rxjs、styled-components、classnames),配合 webpack/rollup 的 tree shaking 特性,引入  ali-react-table 所产生的额外 JS 体积非常有限。

除了上面介绍的一些功能之外,ali-react-table 还提供了许多实用功能,包括表格操作栏、Excel 导出功能等(部分拓展功能需要安装 fusion 组件库)。组件已经在 GitHub 上开源[3],后续我们也会不断更新和维护 ali-react-table 的文档,添加更多的代码示例,欢迎大家使用~

References

[1] https://ali-react-table.js.org/?path=/story/%E7%A4%BA%E4%BE%8B-%E5%9F%BA%E4%BA%8E-crosstable-%E7%9A%84%E9%80%8F%E8%A7%86%E8%A1%A8--pivot-table-based-on-cross-table

[2] https://ali-react-table.js.org/?path=/docs/%E4%BA%A4%E5%8F%89%E4%B8%8E%E9%80%8F%E8%A7%86-%E4%BA%A4%E5%8F%89%E8%A1%A8-%E6%96%87%E6%A1%A3--page

[3] https://github.com/alibaba/ali-react-table

写在最后

方凳雅集是由阿里巴巴B系6大BU(1688,ICBU,零售通,AE,企业金融,考拉)共同维护的公众号奥,我们会定期发送优质好文,欢迎扫码关注

a860276a4aca8fc07c12fff96f3619c6.png

求关注

求转发

34335daf86535a6ebd836cab7c11127a.png5979e996a0639fb1e61993b471c2057d.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543420.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux修改arena大小,Resolume Arena怎么设置大屏幕 调整画面屏幕的方法

如果你想要制作VJ视频&#xff0c;那么Resolume Arena绝对可以满足你的所有需求&#xff0c;小编近期了解到很多用户不知道怎么设置大屏幕&#xff0c;如果你还不知道具体的操作方法&#xff0c;就赶快来看看下面的教程吧&#xff01;操作步骤如下&#xff1a;1、如果你在使用R…

for each循环_Power Query — 循环初步

题记&#xff1a;《Excel圣经》1:3 微软说&#xff0c;“要有循环”&#xff0c;便有了循环。引子&#xff1a;keyword: one of and as each else error false if in is let meta not otherwise or section shared then true try type #binary #date #datetime #datetimezone #…

linux 直接映射 页表大小,linux 启动过程临时页表到底映射了多大内存?

从linux-2.4内核开始&#xff0c;在建立临时页表的时候&#xff0c;一般的教科书都说是映射了8M的物理内存&#xff0c;但是为什么是映射8M呢&#xff1f;当时网上有资料说&#xff0c;8M足够了&#xff0c;但为什么就足够了&#xff0c;一直没有彻底搞清楚&#xff0c;今天又重…

字符串字段当条件查询的时候需要加引号吗_如此详细的SQL优化教程,是你需要的吗?...

基础数据准备二&#xff1a;五百万数据插入上面插入几条测试数据&#xff0c;在使用索引时还需要插入更多的数据作为测试数据&#xff0c;下面就通过存储过程插入500W条数据作为测试数据三&#xff1a;使用索引和不使用索引的比较没有添加索引前一个简单的查询用了1.79秒创建索…

使用CoreImage教程

使用CoreImage教程 CoreImage包含有很多实用的滤镜,专业处理图片的库,为了能看到各种渲染效果,请使用如下图片素材. 现在可以开始教程了: #define FIX_IMAGE(image) fixImageWidth(image, 320.f)// 固定图片的宽度 UIImage * fixImageWidth(UIImage *image, CGFloat width) {f…

电脑生成siri语音_米家智能台灯1S全新升级,支持小爱和Siri的语音控制

夜晚的灯光是我们最为需要的东西&#xff0c;但很多时候&#xff0c;我们需要灯照在不同的地方&#xff0c;平时我只靠吸顶灯的光来照亮家里的每一个角落&#xff0c;甚至是看书的时候都只靠吸顶灯照明。台灯作为占用面积小&#xff0c;光照均匀&#xff0c;让很多的人越来越依…

linux vnc检查,检查Ubuntu VNC设置(避免远程登陆)

(1)安装x11vncsudo apt-get install x11vnc(2)将x11vnc加入xinetdsudo gedit /etc/xinetd.d/x11vnc加入下面这段service x11vnc{ port 5900 type UNLISTED socket_type stream protocol tcp wait …

JavaScript网络地址作为参数_JavaScript之bind的模拟实现

阅读本文约需要5分钟大家好&#xff0c;我是你们的导师&#xff0c;我每天都会给大家分享一些干货内容(当然了&#xff0c;周末也要允许老师休息一下哈)。昨天给大家分享了JavaScript的call和apply的模拟实现&#xff0c;今天给大家分享一下bind的模拟实现。什么是bind&#xf…

cdh集群linux命令,CDH集群中,服务器启动spark2-shell命令行注意事项

1、环境cdh5.12.3spark2 2.3.02、需要本地地洞spark2-shell用于环境测试错误一&#xff1a;Error: A JNI error has occurred, please check your installation and try againException in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Loggerat java.l…

python语音转文字软件_python编写语音转文字软件|语音转文字工具免费版下载(语音批量转换文字) v2.0 最新版_数码资源网...

没有专业的工具怎么能够将语音转换为文字呢&#xff1f;小编为大家提供了语音转文字工具免费版&#xff0c;一款通过Python编写语音转文字软件。用户通过使用语音转文字工具免费版&#xff0c;可以将语音批量转换文字&#xff0c;而且操作也是非常的简单&#xff0c;如果你需要…

Spring-bean作用域scope详解

2019独角兽企业重金招聘Python工程师标准>>> 默认情况下&#xff0c;从bean工厂所取得的实例为Singleton&#xff08;bean的singleton属性&#xff09; Singleton: Spring容器只存在一个共享的bean实例&#xff0c;是默认的配置。 Prototype: 每次对bean的请求都会创…

c语言怎么写星星代码,C语言打印星星的问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include int main(void){int index, up, lines;printf("请输入将要显示的行数:\n");while(scanf("%d", &up) 1){if(up % 2 0){for(lines 1; lines < up / 2; lines){for(index 0; index …

c语言计算机猜数字100以内,求一个猜数字C语言代码,要求如下 计算机生成一个100以内的随机数,玩家来猜 记录猜的次数,最后打...

满意答案itpotato推荐于 2017.10.09采纳率&#xff1a;51% 等级&#xff1a;12已帮助&#xff1a;4600人/**百度知道越来越水了&#xff0c;这么简单的题就一个回答*没见过限定头文件数目的。。而且是限定至少。。。。*/#include#include#include#includeint getrand(){sran…

fakeapp2.2.0下载_软件下载 | SuperCuger 测量平差系统 V1.0

SuperCuger测量平差系统 version 1.0 是一款基于测绘工程中边角网、测角网、测边网、水准网测量数据的免费开源的可视化平差系统。可用于测绘工程中测量平差计算和平差结果报告生成&#xff0c;和插件(中间件)模式扩展新的平差功能。我们的软件具备平差数据可视化&#xff0c;便…

c语言cin输入数组,C++基础:各种输入方法总结cin.get()、

原标题&#xff1a;C基础&#xff1a;各种输入方法总结cin.get()、在C中&#xff0c;各种输入方法还是不少的&#xff0c;而且各有所异&#xff0c;本文做一点简要总结&#xff0c;主要涉及如下内容&#xff1a;cin、cin.get()、cin.getline()、getline()、gets()、getchar()。…

手机怎么能把书签导出来_成人高考能在手机上报名吗?成人高考怎么缴费?

很多成人高考的考生在报名考试的时候想用手机进行报名&#xff0c;但是听说都是使用电脑报名&#xff0c;所以不知道手机报名行不行&#xff0c;另外还有很多考生也不知道如何缴费。那么成人高考能在手机上报名吗?成人高考怎么缴费?下面小编就来和大家聊一聊成人高考手机报名…

thinkphp单入口和多入口的访问方法

完全是参考thinkphp的官网资料 现在, 基本上都是 用 单入口 的方式来做的! thinkphp可创建多入口和单入口两种模式&#xff0c;本文主要讲解创建方法和两者的区别。 TP版本&#xff1a;3.1.3 前端&#xff1a;Home&#xff0c;后台&#xff1a;Admin 一. 创建方法 单入口&#…

财务模块的一些基础概念

财务会计承担着企业总体信息管理和传递的职能&#xff0c;无论企业采用何种运营模式、经营何种业务&#xff0c;都离不开财务的支持&#xff0c;大多数运营和管理流程均与财务存在着接口&#xff0c;为此&#xff0c;优化、高效的财务运作模式和流程成为确保企业良性发展和业务…

if mybatis tk 多个_面试题:mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立关系的?...

前言这是 mybatis 比较常问到的面试题&#xff0c;我自己在以前的面试过程中被问到了2次&#xff0c;2次都是非常重要的面试环节&#xff0c;因此自己印象很深刻。这个题目我很早就深入学习了&#xff0c;但是一直没有整理出来&#xff0c;刚好最近一段时间由于工作太忙&#x…

多机器使用setnx 设置同一个key_Redisson分布式锁的简单使用

做一个积极的人编码、改bug、提升自己我有一个乐园&#xff0c;面向编程&#xff0c;春暖花开&#xff01;一&#xff1a;前言我在实际环境中遇到了这样一种问题&#xff0c;分布式生成id的问题&#xff01;因为业务逻辑的问题&#xff0c;我有个生成id的方法&#xff0c;是根据…