React实现表格选取

本文实例为大家分享了React实现表格选取的具体代码,供大家参考,具体内容如下

在工作中,遇到一个需求,在表格中实现类似于Excel选中一片区域的,然后拿到选中区域的所有数据。

1.实现需求和效果截图

1.获取选中区域的数据
2.选择的方向是任意的
3.支持几行 / 几列的选取
4.通过生产JSON给后台进行交互
5.标记出表头和第一行的数据

React实现表格选取_第1张图片

React实现表格选取_第2张图片

React实现表格选取_第3张图片

React实现表格选取_第4张图片

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数据逻辑 

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 (
        
           
               
                                        {/* */}                
               
                    {                         header.map((item, index) => {                             return
{                                 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}
                        })                     }                
               
                    {                         header.map((item, itemIndex) => {                             return
                                {                                     data[item.name].map((data, dataIndex) => {                                         return
{                                             // 区间选取                                             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}
                                    })                                 }                            
                        })                     }                
           
       
    ) } export default Index

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

你可能感兴趣的:(React实现表格选取)