React实现表格选取
作者:追逐蓦然 时间:2023-08-25 02:56:17
本文实例为大家分享了React实现表格选取的具体代码,供大家参考,具体内容如下
在工作中,遇到一个需求,在表格中实现类似于Excel选中一片区域的,然后拿到选中区域的所有数据。
1.实现需求和效果截图
1.获取选中区域的数据
2.选择的方向是任意的
3.支持几行 / 几列的选取
4.通过生产JSON给后台进行交互
5.标记出表头和第一行的数据
2.核心代码解析
2.1区域选择
onClick={() => {
// 区间选取
if (itemIndex != 0) {
setType('slide')
/**
第一个点击的时候,打开鼠标移动的逻辑
区间选取的时候,要标记第一次选中点的(x,y)坐标。
同时初始化x,y的最小最大值。
**/
if(isStart == 0){
setIsStart(1)
setStartItemIndex(itemIndex)
setStartDataIndex(dataIndex)
setMaxItemIndexs(itemIndex)
setMaxDataIndexs(dataIndex)
setMinItemIndexs(itemIndex)
setMinDataIndexs(dataIndex)
}else {
//第二次点击的时候,关闭鼠标移动的逻辑
setIsStart(0)
}
}
// 行选取
if (itemIndex == 0) {
setType('row')
setIsStart(1)
setColumnIndexList([])
if (rowIndexList.indexOf(dataIndex) != -1) {
let obj = [...rowIndexList]
obj.deleteElementByValue(dataIndex)
setRowIndexList(obj)
} else {
let obj = [...rowIndexList]
obj.push(dataIndex)
setRowIndexList(obj)
}
}
}}
2.2鼠标移动效果
onMouseOver={() => {
if (isStart) {
if(itemIndex!= 0 ){
//比较当前值跟第一次点击值的大小,随时调整最大值和最小值。从而达到选中区域的效果
if (itemIndex > startItemIndex) {
setMinItemIndexs(startItemIndex)
setMaxItemIndexs(itemIndex)
} else {
setMaxItemIndexs(startItemIndex)
setMinItemIndexs(itemIndex)
}
}
if (dataIndex > startDataIndex) {
setMinDataIndexs(startDataIndex)
setMaxDataIndexs(dataIndex)
}
else {
setMaxDataIndexs(startDataIndex)
setMinDataIndexs(dataIndex)
}
}
}}
2.3生产JSON数据逻辑
<Button type="primary" onClick={() => {
if (type == 'slide') {
// 区域选择
// 数据体
let obj = {}
// 表头集合
let headerList = []
// 第一列集合
let firstRow = []
for (let i = minDataIndexs; i <= maxDataIndexs; i++) {
obj[data['数据集'][i]] = []
if(firstRow.indexOf(data['数据集'][i]) == -1){
firstRow.push(data['数据集'][i])
}
for (let j = minItemIndexs; j <= maxItemIndexs; j++) {
let dataObj = {}
dataObj[header[j].name] = data[header[j].name][i]
if(headerList.indexOf(header[j].name) == -1){
headerList.push(header[j].name)
}
obj[data['数据集'][i]].push(dataObj)
}
}
console.log(firstRow);
console.log(headerList);
console.log(obj);
} else if (type == 'row') {
// 几行选中
let obj = {}
let headerList = []
let firstRow = []
rowIndexList.map(item => {
obj[data['数据集'][item]] = []
firstRow.push(data['数据集'][item])
header.map((headerItem, headerIndex) => {
if (headerIndex != 0) {
let dataObj = {}
if(headerList.indexOf(headerItem.name) == -1){
headerList.push(headerItem.name)
}
dataObj[headerItem.name] = data[headerItem.name][item]
obj[data['数据集'][item]].push(dataObj)
}
})
})
console.log(firstRow);
console.log(headerList);
console.log(obj);
} else if (type == 'column') {
// 几列选中
let headerList = []
let firstRow = []
let obj = {}
data['数据集'].map((item, index) => {
obj[item] = []
firstRow.push(item)
columnIndexList.map(i => {
let dataObj = {}
if(headerList.indexOf(header[i].name) == -1){
headerList.push(header[i].name)
}
dataObj[header[i].name] = data[header[i].name][index]
obj[item].push(dataObj)
})
})
console.log(firstRow);
console.log(headerList);
console.log(obj);
}
}}>确定</Button>
3.完成代码
import { Button } from 'antd';
import React, { useState } from 'react';
function Index(params) {
// 删除数组中第一个匹配的元素,成功则返回位置索引,失败则返回 -1。
Array.prototype.deleteElementByValue = function (varElement) {
var numDeleteIndex = -1;
for (var i = 0; i < this.length; i++) {
// 严格比较,即类型与数值必须同时相等。
if (this[i] === varElement) {
this.splice(i, 1);
numDeleteIndex = i;
break;
}
}
return numDeleteIndex;
}
// 表头
const [header, setHeader] = useState([
{
name: "数据集",
},
{
name: '19春支付金额',
},
{
name: '20春支付金额',
},
{
name: '21春支付金额',
},
{
name: '19春支付人数',
},
{
name: '20春支付人数',
},
{
name: '21春支付人数',
}
])
// 数据
const [data, setData] = useState({
'数据集': ['连衣裙', '裤子', '衬衫', '短袖', '长袖', '短裤', '羽绒服', '棉毛裤'],
'19春支付金额': [10000, 5000, 10000, 5000, 10000, 5000, 10000, 5000],
'20春支付金额': [12000, 5200, 12000, 5200, 12000, 5200, 12000, 5200],
'21春支付金额': [14000, 5400, 14000, 5400, 14000, 5400, 14000, 5400],
'19春支付人数': [1000, 500, 1000, 500, 1000, 500, 1000, 500],
'20春支付人数': [1200, 520, 1200, 520, 1200, 520, 1200, 520],
'21春支付人数': [1400, 540, 1400, 540, 1400, 540, 1400, 540],
})
//
const [isStart, setIsStart] = useState(0)
// 类型
const [type, setType] = useState('')
// // 起始
const [startItemIndex, setStartItemIndex] = useState(-1)
const [startDataIndex, setStartDataIndex] = useState(-1)
// 小
const [minItemIndexs, setMinItemIndexs] = useState(-1)
const [minDataIndexs, setMinDataIndexs] = useState(-1)
// 大
const [maxItemIndexs, setMaxItemIndexs] = useState(-1)
const [maxDataIndexs, setMaxDataIndexs] = useState(-1)
// 行下标
const [rowIndexList, setRowIndexList] = useState([])
// 列下标
const [columnIndexList, setColumnIndexList] = useState([])
return (
<div>
<div style={{ marginLeft: 200 }}>
<div style={{ display: 'flex' }}>
<Button type="primary" onClick={() => {
if (type == 'slide') {
// 区域选择
let obj = {}
let headerList = []
let firstRow = []
for (let i = minDataIndexs; i <= maxDataIndexs; i++) {
obj[data['数据集'][i]] = []
if(firstRow.indexOf(data['数据集'][i]) == -1){
firstRow.push(data['数据集'][i])
}
for (let j = minItemIndexs; j <= maxItemIndexs; j++) {
let dataObj = {}
dataObj[header[j].name] = data[header[j].name][i]
if(headerList.indexOf(header[j].name) == -1){
headerList.push(header[j].name)
}
obj[data['数据集'][i]].push(dataObj)
}
}
console.log(firstRow);
console.log(headerList);
console.log(obj);
} else if (type == 'row') {
// 几行选中
let obj = {}
let headerList = []
let firstRow = []
rowIndexList.map(item => {
obj[data['数据集'][item]] = []
firstRow.push(data['数据集'][item])
header.map((headerItem, headerIndex) => {
if (headerIndex != 0) {
let dataObj = {}
if(headerList.indexOf(headerItem.name) == -1){
headerList.push(headerItem.name)
}
dataObj[headerItem.name] = data[headerItem.name][item]
obj[data['数据集'][item]].push(dataObj)
}
})
})
console.log(firstRow);
console.log(headerList);
console.log(obj);
} else if (type == 'column') {
// 几列选中
let headerList = []
let firstRow = []
let obj = {}
data['数据集'].map((item, index) => {
obj[item] = []
firstRow.push(item)
columnIndexList.map(i => {
let dataObj = {}
if(headerList.indexOf(header[i].name) == -1){
headerList.push(header[i].name)
}
dataObj[header[i].name] = data[header[i].name][index]
obj[item].push(dataObj)
})
})
console.log(firstRow);
console.log(headerList);
console.log(obj);
}
}}>确定</Button>
{/* <Button type="primary" danger onClick={()=>{
setStartItemIndex(-1)
setRowIndexList([])
setColumnIndexList([])
setType('')
}}>重置</Button> */}
</div>
<div style={{ display: 'flex', textAlign: "center" }}>
{
header.map((item, index) => {
return <div style={{ minWidth: 100, border: "1px solid #ccc" }} onClick={() => {
setType('column')
setRowIndexList([])
if (columnIndexList.indexOf(index) != -1) {
let obj = [...columnIndexList]
obj.deleteElementByValue(index)
setColumnIndexList(obj)
} else {
let obj = [...columnIndexList]
obj.push(index)
setColumnIndexList(obj)
}
}}>{item.name}</div>
})
}
</div>
<div style={{ display: 'flex', textAlign: "center" }}>
{
header.map((item, itemIndex) => {
return <div>
{
data[item.name].map((data, dataIndex) => {
return <div onClick={() => {
// 区间选取
if (itemIndex != 0) {
setType('slide')
if(isStart == 0){
setIsStart(1)
setStartItemIndex(itemIndex)
setStartDataIndex(dataIndex)
setMaxItemIndexs(itemIndex)
setMaxDataIndexs(dataIndex)
setMinItemIndexs(itemIndex)
setMinDataIndexs(dataIndex)
}else {
setIsStart(0)
}
}
// 行选取
if (itemIndex == 0) {
setType('row')
setIsStart(1)
setColumnIndexList([])
if (rowIndexList.indexOf(dataIndex) != -1) {
let obj = [...rowIndexList]
obj.deleteElementByValue(dataIndex)
setRowIndexList(obj)
} else {
let obj = [...rowIndexList]
obj.push(dataIndex)
setRowIndexList(obj)
}
}
}} onMouseOver={() => {
if (isStart) {
if(itemIndex!= 0 ){
if (itemIndex > startItemIndex) {
setMinItemIndexs(startItemIndex)
setMaxItemIndexs(itemIndex)
} else {
setMaxItemIndexs(startItemIndex)
setMinItemIndexs(itemIndex)
}
}
if (dataIndex > startDataIndex) {
setMinDataIndexs(startDataIndex)
setMaxDataIndexs(dataIndex)
}
else {
setMaxDataIndexs(startDataIndex)
setMinDataIndexs(dataIndex)
}
}
}} style={{
minWidth: 100, border: "1px solid #ccc",
backgroundColor: type == 'slide' ?
(itemIndex >= minItemIndexs && itemIndex <= maxItemIndexs) && (dataIndex >= minDataIndexs && dataIndex <= maxDataIndexs) ? 'pink' : '' :
type == 'row' ? rowIndexList.indexOf(dataIndex) != -1 ? 'pink' : '' :
type == 'column' ? columnIndexList.indexOf(itemIndex) != -1 ? 'pink' : '' : ''
}}>{data}</div>
})
}
</div>
})
}
</div>
</div>
</div>
)
}
export default Index
来源:https://blog.csdn.net/qq_35905501/article/details/120952542
标签:React,表格选取
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
根据选择的checkbox列出选择的值
2008-07-30 12:56:00
![](https://img.aspxhome.com/file/UploadPic/20087/30/200873013437517s.jpg)
JavaScript下利用fso判断文件是否存在的代码
2024-05-02 17:25:30
利用Python制作一个愚人节整蛊消息框
2022-08-07 22:06:53
![](https://img.aspxhome.com/file/2023/8/70898_0s.png)
Python爬取365好书中小说代码实例
2023-05-31 21:25:55
![](https://img.aspxhome.com/file/2023/6/105596_0s.jpg)
使用Python将Mysql的查询数据导出到文件的方法
2024-01-17 21:36:22
python多维列表总是只转为一维数组问题解决
2022-12-27 00:25:21
![](https://img.aspxhome.com/file/2023/0/76920_0s.png)
教你精确编写高质量高性能的MySQL语法
2009-01-14 12:57:00
jquery插件bootstrapValidator表单验证详解
2024-04-22 22:22:05
![](https://img.aspxhome.com/file/2023/5/135835_0s.jpg)
随机显示图片
2009-07-26 10:13:00
mysql中redo log和 binlog的区别
2024-01-14 12:43:52
![](https://img.aspxhome.com/file/2023/7/122867_0s.png)
对python读取CT医学图像的实例详解
2023-12-29 12:36:37
![](https://img.aspxhome.com/file/2023/0/135210_0s.jpg)
准备SQL Server 2008透明数据加密
2009-01-22 14:18:00
Symfony2框架创建项目与模板设置实例详解
2023-11-20 23:36:39
![](https://img.aspxhome.com/file/2023/9/92809_0s.jpg)
python 识别登录验证码图片功能的实现代码(完整代码)
2021-03-14 23:03:40
![](https://img.aspxhome.com/file/2023/7/114547_0s.png)
JS验证逗号隔开可以是中文字母数字
2024-04-19 10:48:08
Python利用Scrapy框架爬取豆瓣电影示例
2022-04-30 15:16:17
![](https://img.aspxhome.com/file/2023/3/86253_0s.png)
Python中shapefile转换geojson的示例
2023-08-03 19:05:04
JavaScript版的DateAdd、DateDiff、IsDate函数
2008-01-30 15:35:00
PHP调用全国天气预报数据接口查询天气示例
2023-11-14 03:11:49
mysql主从服务器同步心得体会第1/2页
2024-01-18 13:34:20