当你对Antd当中的table迷惑时,就进来看看吧

5,192 阅读6分钟

「时光不负,创作不停,本文正在参加2021年终总结征文大赛

导语

在日常开发的过程当中,只要使用antd,就避免不了和table这个组件打交道,因此也会常常碰撞出问题的火花🧨🧨🧨,这里就记录一下鄙人在最近一次项目开发中,遇到的一些问题,目前主要涉及到table当中的样式问题、key,以及可选中、可扩展table涉及到的问题,之后还会持续更新。✨✨

关于table的样式问题

列的样式

我们一般给整个table设置一些样式时,会选择直接给这个Table加上一个className的属性来控制,但是如果想要给每一列单独加上一些样式时,Antd在Column当中也为我们提供了className的属性,不过当遇到修改某一列的样式时,鄙人通常是在render当中渲染的dom节点中添加样式

For example:

{
        key: 'ips',
        title: 'IPS',
        render: (n, cn) => {
          return <div style={{ maxWidth: 320 }}>{n.id === -1? '***':n.ips}</div> 
        }
}

行的样式

当你想要给行增加一些样式的时候,首先Antd为我们提供了一个rowClassName的属性,不过遇到修改行样式的情况很少,这一部分,作为新人,鄙人会在进行切身实践之后再进行细致的补充,避免误人子弟呀!👀👀

其他样式

关于样式,鄙人只有一条经验法则,就是多去控制台当中调试调试,当你想不通为什么你改了Table的一些样式没有出现的时候,就去控制台当中看看到底是哪句代码控制了现在的呈现效果。举一个小小的例子:这次项目当中ui同学觉得Table当中每一行默认的行高有点过大,想让鄙人改小一点✌

table01.png

万事第一步,看文档。我过来瞅了瞅API当中所有Table的属性,发现并没控制行高的,于是就在控制台中找啊找,终于发现了,原来padding这个东西,是Table当中行高的罪魁祸首

.ant-table-thead>tr>th, .ant-table-tbody>tr>td {
    padding: 16px;    //当你修改时,会发现行高在跟着变化
    overflow-wrap: break-word;
}
.commonTable table tbody tr td {
    padding: 11px 16px !important;     //进行这样的修改,就大功告成👌
}

通过看控制台,我们改的时候就知道从哪里下手了。

温馨提示一句,很多时候我们修改table样式的时候出现不生效的情况,只需要加上!important就ok啦!😜😜

table当中key的作用

(样式只是table当中一个很小很小的一方面,鄙人发现真正神奇的是这个神秘的key👼👼👼)

首先,我们都知道按照React的王国当中,一直都很重视key的存在,所有的数组组件必须绑定 key。在 Table 中,dataSourcecolumns 里的数据值都需要指定 key 值。对于 dataSource 默认将每列数据的 key 属性作为唯一的标识。但是,这里我要讲的key,可不是dataSourcecolumns 当中的key,而是整个Table的key,就像下面这样:

<Table
    key={selected.id}  //key👈👈👈
    rowKey={(record) => record.id}  //rowKey
    className={Styles.commonTable}
    rowSelection={rowSelection}
    columns={_this.getColumns() }
    dataSource={TableList}               
/>

当你遇到如下情景:

当多个Tab下的表格进行切换时,你的分页或者过滤的条件竟然没有被重置,还保留了上一个Tab当中Table的值;❓❓

或者当你调用了某一个方法,想要对表格重新渲染时,突然就不知所措了。⁉⁉

这个时候,就可以给你的Table设置一个key作为标识啦!每当你想要重新重新渲染这个Table的时候,就可以改变一下它的key,这样就不会出现上面两种你不知所措的情况啦!🎉🎉

就比如,第一种情况当中,你给每一个Tab设一个id,并将这个id作为Table的key标识,这样无论你在上一个Tab当中做了多少操作,当切换到下一个Tab当中,这个Table都会重新渲染,不会保留上一个Table的任何东西。

仔细想想,这其实是组件key在Table当中的一个小小的应用而已。 不管是不是Table,你给任何一个组件设置一个key标识,只要改变都会触发重新渲染。以下是鄙人觉得很好的一个小例子:

Here,用到了可扩展表格,可扩展表格<RowExpend/>做为子组件放在父组件<Table/>当中,同时在父组件当中有一个转移和删除的方法。现在要实现选中<RowExpend/>当中的行,在父组件当中调用删除或转移的方法,对子组件的数据进行更改。

table02.png

其实做转移和删除的操作对我们来说并不困难,只是调一个接口而已,但是有过开发经验的大家应该都知道,再进行删除或转移的操作之后,我们需要重新请求一下表格的数据,把最新的数据展示给用户,这时就有问题了,如果是在父组件<Table/>里维护子组件的数据那就好说,但偏偏是子组件自己维护自己的表格数据(在子组件的渲染时调用获取table数据的接口)。问题就转化成了,父组件执行某一操作之后,子组件如何自己进行重新渲染?

最后在大佬的指导之下,鄙人采用了时间戳的方式:

给子组件的key加上一个时间戳,当执行一次删除或者转移后,就更新一下这个时间戳,这样子组件就会重新渲染,并重新请求到最新的数据啦!!!

<RowExpand
      key={record.id + upDateTime}
      {...this.props}
/>

不得不说,时间戳和key标识这对cp可真是太好用了,反正我是嗑到了,不知道在座的各位是不是学到了。💪💪💪

说完了key,再来讲讲rowKey吧!

如果说,上面讲的key只是所有组件共有的一个属性key的一个小小应用,那么rowKey对于组件来说,就是Table独有的一个属性啦!

在API当中,是这样写道的

rowKey: 表格行 key 的取值,可以是字符串或一个函数

之前,鄙人一直没有意识到,这个rowKey到底有上面用,直到遇到了rowSelection表格勾选框。

Table组件当中,当涉及到勾选框的时候,往往会有如下的配置:

const rowSelection = {
      selectedRowKeys,    //选中行的rowKey
      onChange: this.onSelectChange,  //当选中项发生改变时的操作
      getCheckboxProps: this.getCheckboxProps //设置每行勾选框的属性
};

还没验证过准确不准确(有经验的友友,或者有时间的友友可以验证一下😮😮),鄙人觉得一般来说这个Rowkey是你dataSource 当中每一条数据里的key的值,但是后端也不知道每一条数据里最好有一个key属性,所以通常都没有,这个时候Rowkey就是从0开始取,0,1,2,3....

那我们如果不想要默认的这个Rowkey,更希望把每一条数据的id作为Rowkey该怎么办呢?

难道要遍历一遍数据,给每一条数据加一个key属性吗? NoNoNo,只需要一句话即可:

<Table
    key={selected.id}
    rowKey={(record) => record.id}  //一句话搞定
    ....
/>

这样的话,我们在获取到所勾选数据的id就方便很多啦!

未完待续。。。(暂时更到这里了,前端新人,这只是一次项目当中的些许体会,之后会继续加料滴!!!👻👻👻)