likes
comments
collection
share

你们前端可以实现:Table最后一列只展示详细信息吗?

作者站长头像
站长
· 阅读数 17

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 3 天,点击查看活动详情

项目背景

UI设计了一个表格:[1] 最后一列用来展示详情;[2] 表格左侧点击行切换;[3] 要求选中行的样式和详情信息用一个边框凸显出来。

UI在介绍完自己的设计后,略微挑衅地问前端:“这个表格你们前端能实现吗?”

前端:“可以!”

UI有些惊讶地问:“有组件支持吗?”

前端:“没有!”

产品接着说:“那会议结束后前端评估下可行性,和开发周期...”

前端:“目测两小时就能搞定。”

看着大家惊愕😧的表情,我淡淡地笑了笑,心想天下武功,无坚不摧...

你们前端可以实现:Table最后一列只展示详细信息吗?

牛是吹出去了,会议过后赶紧行动起来。第一方案:是Ant Design合并单元格,再覆盖样式;第二方案自己动手实现一个表格,大不了加会班,还能让UI给看低了不成?

实现过程

首先找到Ant Design合并单元格的Demo,然后用在线编辑器先实现个初始版本

你们前端可以实现:Table最后一列只展示详细信息吗?

我是新建项目,大家如果要用,需要注意下版本差异

首先是删掉多余的行和列,简化项目代码:

const columns = [
  {
    title: 'Name',
    dataIndex: 'name',
    render: (text) => <a>{text}</a>,
  },
  {
    title: 'Age',
    dataIndex: 'age',
  },
  {
    title: 'Home phone',
    dataIndex: 'tel',
    onCell: (_, index) => {
      if (index === 0) {
        return {
          rowSpan: 5,
        };
      }
      return {rowSpan: 0};
    },
  }
];

改造了column配置,onCell配置用第一行数据的单元格,平铺占满:效果如下图,已经有初步的雏形了。

你们前端可以实现:Table最后一列只展示详细信息吗?

接下来做表格行点击选择,通过查阅API文档,我们发现rowClassName这个属性可以设置单行的class,那么可以通过设置这个方法对选中行添加单独的class;

查阅文档,我们知道onRow方法可以控制表格每行的鼠标交互事件,于是点击选择行的核心代码就实现了:


import React, {useState} from 'react';
import { Table } from 'antd';

const App = () => {
  const [selectIndex, setSelectIndex] = useState(0);
  return (
    <Table 
      columns={columns} 
      dataSource={data}
      pagination={false}
      onRow={(record,index) => {
        return {
          // 点击行
          onClick: event => {
            setSelectIndex(index)
          }, 
        };
      }}
      rowClassName={(record,index)=>{
        if(index === selectIndex) return 'selectedRow';
        return '';
      }}
    />
  )
};

当然更推荐大家用id之类的唯一键,作为选中标示,因我这里是在线初始版本就怎么快怎么来了。

接下来就来到CSS覆盖频道了,实现选中行包围详情背景➕边框了:

.ant-table-tbody > :first-child > :last-child {
  background: #f1f1ff;
  border: 1px solid red;
}

.selectedRow .ant-table-cell {
  background-color: #f1f1ff;
  background: #f1f1ff;
  border: 1px solid red;
  border-left: none;
  border-right: none;
  position: relative;
}

.selectedRow>:first-child {
  border-left: 1px solid red;
  border-radius: 2px 0 0 2px;
}

.selectedRow .ant-table-cell::after {
  content:' ';
  position:absolute;
  width: 4px;
  height: 54px;
  background: #f1f1ff;
  right: -2px;
  top: 0px;
  z-index: 999;
}

.ant-table-tbody > :first-child > :last-child::after {
 display: none;
}

.selectedRow .ant-table-cell-row-hover {
  background-color: #f1f1ff !important;
  background: #f1f1ff !important;
}

颜色随手写的,有点丑,不影响功能

上面这些CSS都是常规操作,:[1] 核心逻辑是给selectedRow下面的每个单元格加边框、加背景[2] 然后通过每个单元格的after伪类覆盖掉不需要的边框。📖 大家有更好的思路欢迎评论区留言:

你们前端可以实现:Table最后一列只展示详细信息吗?

到这一步,悬着的心才终于放下了,八九不离十了。

最后是在右侧单元格上显示选中行的详情了,[1] 这一步我的实现思路是直接把columns改造成函数,传入选中行下标作为参数;[2] 最后在右侧单元格的render方法中获取到选中行的数据,然后展示详细信息:

const columns = (index)=>[
  {
    title: 'Name',
    dataIndex: 'name',
    render: (text) => <a>{text}</a>,
  },
  {
    title: 'Age',
    dataIndex: 'age',
  },
  {
    title: 'Home phone',
    dataIndex: 'tel',
    onCell: (_, index) => {
      if (index === 0) {
        return {
          rowSpan: 5,
        };
      }
      return {rowSpan: 0};
    },
    render:()=>{
      const current = data[index];
      return <div>
        <div>name:{current.name}</div>
        <div>age:{current.age}</div>
        <div>phone:{current.phone}</div>
        <div>address:{current.address}</div>
      </div>;
    }
  },
];
// 调用时columns传入唯一标识就好了
// <Table columns={columns(selectIndex)} ...

这样改造之后,点击就可以显示具体详情了,实际项目中还是要改回 id 之类的唯一健

你们前端可以实现:Table最后一列只展示详细信息吗?

至此可以满意的了😊。一个小时就完成了,今天可以不用加班了,开森~😄

尾声

[叮叮...]

手机突然响了,原来群里UI发出了最新版设计稿

我打开设计稿,特意看了看刚实现的表格:啥?改版了?详细信息改用弹窗展示...🤬🤬

你们前端可以实现:Table最后一列只展示详细信息吗?

当现实拍在人脸上时,不经让人感叹:前端的工作总是那么丰富多彩却毫无用处...

转载自:https://juejin.cn/post/7135864815163015175
评论
请登录