React antd Table 实现单元格点击 表头斜线分组等功能
先上成品示意图:
几个关键步骤:
一 定义数据结构:
export const data = [{key: 'row1',beforeUpdateLevel: '等级1',level_1: '保',level_2: '升',level_3: '升',level_4: '未设置',level: 1, // 表示当前行变更前为等级1},{key: 'row2',beforeUpdateLevel: '等级2',level_1: '降',level_2: '保',level_3: '升',level_4: '升',level: 2,},{key: 'row3',beforeUpdateLevel: '等级3',level_1: '降',level_2: '未设置',level_3: '未设置',level_4: '升',level: 3,},{key: 'row4',beforeUpdateLevel: '等级4',level_1: '降',level_2: '未设置',level_3: '未设置',level_4: '未设置',level: 4,},
];
二 实现表头分组:
利用column--->title属性 实现表头对角线分组" data-link-title="antd Table-->column--->title属性 实现表头对角线分组">antd Table-->column--->title属性 实现表头对角线分组
const columns = [// 利用title可以返回ReactNode属性 和 css 实现分组{title: (<div className={styler.headerCell}><div className={styler.afer}>变更后等级</div><div className={styler.before}>变更前等级</div></div>),dataIndex: 'beforeUpdateLevel',key: 'beforeUpdateLevel',// 固定分组这一栏的宽度width: 220,align: 'center',},{title: '等级1',dataIndex: 'level_1',align: 'center',key: 'level_1',},{title: '等级2',dataIndex: 'level_2',align: 'center',key: 'level_2',},{title: '等级3',dataIndex: 'level_3',align: 'center',key: 'level_3',},{title: '等级4',dataIndex: 'level_4',align: 'center',key: 'level_4',},];
css 实现画对角线:
.headerCell {// 画三角形border-top: 43px rgb(250 250 250) solid;/*上边框宽度等于表格第一行行高*/width: 0px;/*让容器宽度为0*/height: 0px;/*让容器高度为0*/border-left: 237px #f8fbff solid;/*左边框宽度等于表格第一行第一格宽度*/position: relative;.afer {position: absolute;top: -36px;left: -70px;width: 60px;color: #666666;}.before {position: absolute;top: -24px;left: -226px;width: 60px;color: #666666;}// 伪元素画分割线&::after {content: '';position: absolute;width: 1px;height: 237px;top: -140px;left: -120px;background-color: rgb(239 239 239);display: block;transform: rotate(-80deg);}}
注意:
固定分组表头的宽度,否则响应式可能会引起表头斜线错位等问题
三:添加单元格点击事件 设置选中状态
利用onCell属性为单元格添加点击事件
// 设置第一个单元格为默认选中const [active, setActive] = useState('row1_level_1');const newColums = columns.map((col, index) => {return {...col,onCell: (record) => ({record,dataIndex: col.dataIndex,title: col.title,onClick: () => cellHandleClick(record, col),}),};});const cellHandleClick = (record, col) => {const { key } = record;const { dataIndex } = col;// 利用record和col的组合keysetActive(`${key}_${dataIndex}`);
};
四:完整代码
import React, { useState, useEffect } from 'react';
import { Popover, Table, Tag } from 'antd';
import { data } from './data';
import classNames from 'classnames';
import DownPopover from './DownPopover';
import StayPopover from './StayPopover';
import UpPopover from './UpPopover';
import styler from './index.less';
import { history } from 'umi';export default function ViewFlow({ onCellClick }) {const [active, setActive] = useState('row1_level_1');const SettingCell = ({title,dataIndex,children,record,...restProps}) => {let childNode = children;const [show, setShow] = useState(false);useEffect(() => {}, [show]);const handleOver = () => {setShow(true);};const handleOut = () => {setShow(false);};const SettingBtn = (<divclassName={styler.settingBtn}onClick={() => handleGoSetting(record, dataIndex)}>去设置</div>);const renderText = (record, dataIndex) => {const { level } = record;const [_, currentLevel] = dataIndex.split('_');const text = record?.[dataIndex];switch (text) {case '未设置':return show ? SettingBtn : <div className={styler.base}>{text}</div>;case '保':return (<Itemtext={text}level={level}currentLevel={currentLevel}color="#3880FF"background="rgba(56, 128, 255, 0.05)"/>);case '降':return (<Itemtext={text}level={level}currentLevel={currentLevel}color="#FF3D00"background="rgba(255, 61, 0, 0.05)"/>);case '升':return (<Itemtext={text}level={level}currentLevel={currentLevel}color="#24B488"background="rgba(36, 180, 136, 0.05)"/>);default:return text;}};childNode = renderText(record, dataIndex);const key = `${record?.key}_${dataIndex}`;return (<tdonMouseOut={handleOut}onMouseOver={handleOver}{...restProps}className={classNames({ active: key === active },{ firstColumnClass: dataIndex === 'beforeUpdateLevel' },)}>{childNode}</td>);};const ItemMap = {升: UpPopover,降: DownPopover,保: StayPopover,};const Item = ({ color, background, text, level, currentLevel }) => {const Content = ItemMap[text];return (<Popovercontent={<Content level={level} currentLevel={currentLevel} />}placement="bottomRight"><div className={styler.text}><div style={{ color, background }}>{text}</div></div></Popover>);};const handleGoSetting = (record, dataIndex) => {const { level } = record;const [, levelNum] = dataIndex.split('_');};const cellHandleClick = (record, col) => {const { key } = record;const { dataIndex } = col;setActive(`${key}_${dataIndex}`);};const columns = [{title: (<div className={styler.headerCell}><div className={styler.afer}>变更后等级</div><div className={styler.before}>变更前等级</div></div>),dataIndex: 'beforeUpdateLevel',key: 'beforeUpdateLevel',width: 220,align: 'center',},{title: '等级1',dataIndex: 'level_1',align: 'center',key: 'level_1',},{title: '等级2',dataIndex: 'level_2',align: 'center',key: 'level_2',},{title: '等级3',dataIndex: 'level_3',align: 'center',key: 'level_3',},{title: '等级4',dataIndex: 'level_4',align: 'center',key: 'level_4',},];const newColums = columns.map((col, index) => {return {...col,onCell: (record) => ({record,dataIndex: col.dataIndex,title: col.title,onClick: () => cellHandleClick(record, col),}),};});const components = {body: {cell: SettingCell,},};return (<div className={styler.content}><Tablecomponents={components}columns={newColums}bordereddataSource={data}pagination={false}/></div>);
}
data.js
export const data = [{key: 'row1',beforeUpdateLevel: '等级1',level_1: '保',level_2: '升',level_3: '升',level_4: '未设置',level: 1, // 表示当前行变更前为等级1},{key: 'row2',beforeUpdateLevel: '等级2',level_1: '降',level_2: '保',level_3: '升',level_4: '升',level: 2,},{key: 'row3',beforeUpdateLevel: '等级3',level_1: '降',level_2: '未设置',level_3: '未设置',level_4: '升',level: 3,},{key: 'row4',beforeUpdateLevel: '等级4',level_1: '降',level_2: '未设置',level_3: '未设置',level_4: '未设置',level: 4,},
];
index.less
.content {.base {padding: 5px 0px;color: #c8c8c8;width: 60px;display: inline-block;}.settingBtn {box-sizing: border-box;display: inline-block;background: rgba(56, 128, 255, 0.1);border: 1px solid rgba(56, 128, 255, 0.5);padding: 4px;width: 60px;border-radius: 2px;color: #3880ff;}.text {box-sizing: border-box;width: 60px;padding: 4px 0;display: inline-flex;justify-content: center;align-items: center;div {width: 20px;height: 20px;border-radius: 50%;background: rgba(56, 128, 255, 0.05);}}.headerCell {// 画三角形border-top: 43px rgb(250 250 250) solid;/*上边框宽度等于表格第一行行高*/width: 0px;/*让容器宽度为0*/height: 0px;/*让容器高度为0*/border-left: 237px #f8fbff solid;/*左边框宽度等于表格第一行第一格宽度*/position: relative;.afer {position: absolute;top: -36px;left: -70px;width: 60px;color: #666666;}.before {position: absolute;top: -24px;left: -226px;width: 60px;color: #666666;}// 伪元素画分割线&::after {content: '';position: absolute;width: 1px;height: 237px;top: -140px;left: -120px;background-color: rgb(239 239 239);display: block;transform: rotate(-80deg);}}:global {.firstColumnClass {background: #f8fbff;}.active {background: linear-gradient(0deg,rgba(56, 128, 255, 0.05),rgba(56, 128, 255, 0.05));// border: 1px solid #3880ff;// border-right: 1px solid #3880ff !important ;// box-sizing: border-box;box-shadow: 0px 0px 2px #3880ff inset;}.ant-table-thead {height: 30px;}.ant-table-tbody > tr > td {padding: 8px 0px;}.ant-table.ant-table-bordered> .ant-table-container> .ant-table-content> table> thead> tr> th {padding: 0;}// .ant-table-tbody > tr > td :first-child {// background: #f8fbff;// &:hover {// background: #f8fbff;// }// }background: #f8fbff;// .ant-table-tbody > tr > td:nth-child(2) {// background: #bae7ff;// }.ant-table-tbody > tr > td:hover {cursor: pointer;background: linear-gradient(0deg,rgba(56, 128, 255, 0.05),rgba(56, 128, 255, 0.05));}}
}
DownPopver.jsx
import React from 'react';
import { Popover, Space, Tag, Typography } from 'antd';
export default function DownPopover({ level, currentLevel }) {return (<Space size={10} direction="vertical"><Tag color="#FF3D00">降级</Tag><><Typography.Text type="secondary">变更前等级:<Typography.Text>等级{`${level}`}</Typography.Text></Typography.Text><Typography.Text type="secondary">变更后等级:<Typography.Text>等级{`${currentLevel}`}</Typography.Text></Typography.Text></></Space>);
}
StayPopover.jsx
import React from 'react';
import { Popover, Space, Tag, Typography } from 'antd';
export default function StayPopover({ level, currentLevel }) {return (<Space size={10} direction="vertical"><Tag color="#599CFF">保级</Tag><><Typography.Text type="secondary">保级等级:<Typography.Text>等级{`${currentLevel}`}</Typography.Text></Typography.Text></></Space>);
}
UpPopover.jsx
import React from 'react';
import { Popover, Space, Tag, Typography } from 'antd';
export default function UpPopover({ level, currentLevel }) {return (<Space size={10} direction="vertical"><Tag color="#24B488">升级</Tag><><Typography.Text type="secondary">变更前等级:<Typography.Text>等级{`${level}`}</Typography.Text></Typography.Text><Typography.Text type="secondary">变更后等级:<Typography.Text>等级{`${currentLevel}`}</Typography.Text></Typography.Text><Typography.Text type="secondary">状态:<Typography.Text>启用</Typography.Text></Typography.Text></></Space>);
}
React antd Table 实现单元格点击 表头斜线分组等功能相关推荐
- vue中用table_Vue中table合并单元格用法
地名 结果 人名 性别 {{item.name}} 已完成 未完成 {{item.groups[0].name}} {{item.groups[0].sex}} {{item.groups[son]. ...
- 解决element-ui中表格行点击事件和表格单元格点击事件冲突的问题
element-ui中如果同时设置了表格行点击事件和表格单元格点击事件的化,当点击单元格的时候会因为事件冒泡触发表格行点击事件,这不是我们需要的 要解决这种事件冲突的问题,只需要在单元格的点击事件上加 ...
- html table 合并单元格 分页,Word表格跨页,合并单元格后,希望跨页的每一页都显示合并单元格的内容(有图)...
回答: 一.使用Excel开始菜单中的合并功能 Excel表格中合并单元格有很多中形式,比如:合并居中.合并单元格.按行合并.跨列居中.合并相同单元格和合并内容.接下来看看具体操作步骤吧! 步骤:选中 ...
- itext隐藏table的单元格边框
隐藏table的单元格边框 PdfPCell的方法disableBorderSide(1); 参数为int型. 其中具体参数: //隐藏上边框 // cell.disableBorderSide(1) ...
- 表格合并行的方法和单元格点击事件
el-table部分 <el-table max-height="100%" @cell-click="cellClick":data="dat ...
- Table合并单元格,表格居中,内容居中显示
例如:新建一张四行四列的表格,第一行的四列合并,第二.三.四行的第一列合并在一起居中显示 <%@ page language="java" contentType=" ...
- element plus的table合并单元格
element的table合并单元格 就element+中的el-table中的span-method方法的使用和遇到的一些问题 如果想要将后一列挨着的单元格合并,return 1,2,但是得将后一个 ...
- Layui table表格单元格合并问题
Layui table表格单元格合并 人丑话不多, 直接上方法: /*** * @param fieldName 要合并列的field属性值* @param index 表格的索引值 从1开始* @d ...
- js实现 table合并单元格
** table合并单元格 function uniteTdCells(tableId){var table = document.getElementById(tableId);for (let i ...
最新文章
- 阿里巴巴Druid,轻松实现MySQL数据库加密!
- go语言笔记——map map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序...
- boost::lockfree::detail::tagged_ptr用法的测试程序
- shell脚本实现无密码交互的SSH自动登陆
- linux mysql 最小安装,Linux最小化安装之安装mysql
- 交流伺服系统设计指南_交流设计
- 测试驱动开发 测试前移_为什么测试驱动的开发有用?
- C++设计模式之二 AbstractFactory模式
- 【Java】计算符号函数的值
- linux安装mysql5.7.29_linux 之centos7搭建mysql5.7.29的详细过程
- 阿里云的RDS 查看binlog日志的方法
- 【Elasticsearch】zen discovery集群发现机制
- UML与软件建模 第五次作业
- DDoS booter滥用 DTLS 服务器放大攻击
- list转有序map
- Unity 随机生成中文名字
- PKU ACM 1008 玛雅历
- 【VOLTE】【SRVCC】【2】 VOLTE SRVCC(SRVCC TO 3GPP2/CDMA1X)
- GDAL综合整理--7:GDAL实用工具简介
- 这个春天,邀你一起探寻AI与青春的碰撞之力
热门文章
- FTP服务器配置实例(匿名用户、本地用户、虚拟用户)
- 如何查看linux上的ftp服务器配置,ftp服务器配置:如何在Linux上搭建FTP服务器?
- 决策易|营销管理,让流向数据说话!
- [Asp.net]web.config customErrors 如何设置?
- Excel VBA解析JSON数据
- 面试常问集锦——线上排查部分
- vue canvas 方法无效_3 分钟,教会你如何用 Vue 实现 Google 搜索中灭霸的无限手套...
- MapReduce编程
- 使用PyQt5写一个桌面程序
- 【Java】一文秒懂http请求获取FlexManager某设备分组监控点