详解和实现数据表格中的行数据合并功能


theme: smartblue

前言

需求场景:

在提供了数据查看和修改的表格视图中(如table、a-table等…),允许用户自行选择多行数据,依据当前状态进行特定列数据的合并操作。选中的数据将统一显示为选中组的首条数据值。同时,页面会即时反馈显示合并后的效果,提供直观的操作反馈。

效果

image.png

方案选型

依赖库:vxe-table(:merge-cells="mergeCells"用作效果展示)

核心逻辑

根据数据行中的mergeId是否相等判断是否有过合并操作,前端执行合并操作后需将合并的数据的mergeId设置为相同的数值,并将选中数据中需要合并的数据项置为第一行选中的数据,并在页面展示合并后的效果。

保证两个一致:

  • 数据一致性(数据覆盖) 优先级:极高
  • 展示一致性(根据mergeId调整展示) 优先级:高

数据源举例

描述: 常规的后端返回结构,数组对象,数组中每一项指代每一条数据。

列表数据示例:

data:[
{mergeId:1,...},
{mergeId:2,...},
{mergeId:3,...}
]

合并逻辑:

- 数据一致性

coverParams:需要覆盖的参数名,存在于列表数据中

firstData:第一条数据

selectRows:选中的数据集合

 coverParams.forEach(item => {
      for (let i = 1; i < number; i++) {
        // 选中的数据都覆盖第一条数据的值
        selectRows[i][item] = firstData[item];
        // }
      }
    });

- 展示一致性

newCurrentRows:由于选择时的随机性和数据结构的不稳定性,记录点击的位置点,并将位置点排序记录。

// 生成正序数组newCurrentRows
    const newCurrentRows = currentRows.sort((a, b) => a - b);
// 若newCurrentRows数据不连续 则将选中数据都置为队尾
    const isEqual = newCurrentRows.every((value, index, array) => {
      if (index === 0) {
        return true;
      } else {
        return value === array[index - 1] + 1;
      }
    })

情况1:选中的数据连续

coverCols:需要合并的行号组,字段的展示位置,用作生成mergeCells

firstRow:第一行位置

number:对应rowspan,得到跨几行的数据

// 获取选中了几条数据
    const number = state.selectRows.length;
  // 取第一个行号
    const firstRow = newCurrentRows[0];
if (isEqual) {
const mergeCellsArr = [];
      coverCols.forEach(item => {
        mergeCellsArr.push({
          row: firstRow,
          col: item,
          rowspan: number,
          colspan: 1
        });
      });
      mergeCells.value = mergeCellsArr;
}

情况2:选中的数据不连续

核心处理:将不连续的数据处理取出放置队尾,满足连续条件继续操作。

      // 非选中的数据
      const fristElements = [];
      // 选中的数据集合
      const secondElements = [];
      // // 选中的数据置于队尾
      // // 遍历原始数组
      const dataNumber = dataSource.value.length;
      for (let i = 0; i < dataNumber; i++) {
        // 如果i在 newCurrentRows中不存在,则将其置于fristElements前列
        if (!newCurrentRows.includes(i)) {
          fristElements.push(dataSource.value[i]);
        }
        // // 如果i在 newCurrentRows中存在,则将其置于fristElements后列
        if (newCurrentRows.includes(i)) {
          secondElements.push(dataSource.value[i]);
        }
      }
      const newSecondElements = secondElements.map(item => {
        return {
          ...item
        };
      });
      // 将新数组的元素追加到原始数组的末尾
      dataSource.value = fristElements.concat(newSecondElements);

存在合并标识的数据处理

主要用作数据中存在mergeId标记如何展示合并效果。

// 初始数据根据mergeId组装合并效果
  const baseDataMerge = () => {
    // coverCols 需要合并的列号  注塑全新
    const baseCoverCols = getCoverCols();
    // length 需要合并的行数
    const mergedCells = [];
    dataSource.value.forEach((row, rowIndex) => {
      //检查当前行的mergeId是否和下一行的mergeId一样  且mergeId存在
      if (
        rowIndex < dataSource.value.length - 1 &&
        row.mergeId === dataSource.value[rowIndex + 1].mergeId &&
        row.mergeId !== undefined
      ) {
        // 仅在第一次符合条件时 判断横跨几行  默认跨两行
        if (
          dataSource.value[rowIndex + 3] &&
          row.mergeId === dataSource.value[rowIndex + 3].mergeId
        ) {
          // 横跨3行
          state.mergeLength = 4;
        } else if (
          dataSource.value[rowIndex + 2] &&
          row.mergeId === dataSource.value[rowIndex + 2].mergeId
        ) {
          // 横跨4行
          state.mergeLength = 3;
        } else {
          // 横跨2行
          state.mergeLength = 2;
        }
        baseCoverCols.forEach(item => {
          mergedCells.push({
            row: rowIndex, // 开始行,由符合条件的
            rowspan: state.mergeLength, // 合并行数,由选中的数据条数决定
            col: item,
            colspan: 1
          });
        });
        state.mergeFlag = true;
      }
    });
    console.log('初始数据合并效果', mergedCells);
    return mergedCells;
  };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/676314.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s怎么监听资源的变更

监听k8s所有的 Deployment 资源 package mainimport ("context""fmt"v1 "k8s.io/api/apps/v1""k8s.io/apimachinery/pkg/util/json""k8s.io/client-go/informers""k8s.io/client-go/kubernetes""k8s.io/cli…

linux,lseek,append用法

打开写的.c文件 内容为 代码 <sys/stat.h> #include <fcntl.h> #include<stdio.h> #include<unistd.h> #include<string.h>//off_t lseek(int fd, off_t offset, int whence); //int open(const char *pathname, int flags); //int open(const …

一个AI板卡电脑--香橙派 AIpro

本文算是一个开箱测评&#xff0c;主要评估它和一个电脑的距离。 香橙派官网&#xff1a;香橙派(Orange Pi)-Orange Pi官网-香橙派开发板,开源硬件,开源软件,开源芯片,电脑键盘香橙派&#xff08;Orange Pi&#xff09;是深圳市迅龙软件有限公司旗下开源产品品牌;香橙派&#x…

【触想智能】工业平板电脑在高铁上的应用分析

随着科技的快速发展&#xff0c;平板电脑作为一种新型的电子设备&#xff0c;已经逐渐成为人们日常生活中的必需品。而工业平板电脑则是一种更为专业的平板电脑&#xff0c;可以应用于各种工业领域&#xff0c;如交通、制造业、医疗、金融、人工智能等。 今天&#xff0c;小编为…

Oracle Hint /*+APPEND*/插入性能总结

oracle append用法 Oracle中的APPEND用法主要用于提高数据插入的效率。 基本用法&#xff1a;在使用了APPEND选项后&#xff0c;插入数据会直接加到表的最后面&#xff0c;而不会在表的空闲块中插入数据。这种做法不需要寻找freelist中的free block&#xff0c;从而避免了在…

推荐一个图片识别的llama3微调版本 清华面壁项目

水一篇&#xff1a; MiniCPM-V是面向图文理解的端侧多模态大模型系列。该系列模型接受图像和文本输入&#xff0c;并提供高质量的文本输出。自2024年2月以来&#xff0c;我们共发布了4个版本模型&#xff0c;旨在实现领先的性能和高效的部署&#xff0c;目前该系列最值得关注的…

36【Aseprite 作图】蒸笼盖——拆解

1 蒸笼盖框架 里圈和外圈的形状都是一样的 扶手处&#xff0c;2 1 2 2 2&#xff08;最好都是2&#xff0c;拐角处用1&#xff09; 2 上色 中间的波浪&#xff0c;是2 2 2 上&#xff08;再 2 2 2 下&#xff09; 下方阴影&#xff0c;左边的阴影&#xff0c;右边的阴影颜色…

【Elasticsearch】es基础入门-02.RestClient操作索引库

RestClient操作索引库 示例&#xff1a; 一.分析数据结构&#xff0c;写索引库 #酒店的mapper PUT /hotel {"mappings": {"properties": {"id":{"type": "keyword"},"name":{"type": "text",…

p5开发helloworld

注意&#xff0c;执行的时候&#xff0c;后面不用带class的后缀

速递FineWeb:一个拥有无限潜力的15T Tokens的开源数据集

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

SuperMap GIS基础产品FAQ集锦(20240603)

一、SuperMap iDesktopX 问题1&#xff1a;请教一下&#xff0c;桌面把火星坐标系的数据投影转换为4326坐标系数据如何才能没有偏移呢&#xff1f; 11.1.1 【解决办法】可以使用iDesktopX提供的“电子地图坐标转换”插件实现对火星坐标系数据的纠偏。 问题2&#xff1a;请教…

基于鲲鹏服务器搭建简单的开源论坛系统(LAMP)实践分享

LAMPLinux apache mysql( mariadb) PHP 结合利用华为云弹性负载均衡ELB弹性伸缩AS服务 优点&#xff1a; 将访问流量自动分发到多台云服务器&#xff0c;扩展应用系统对外的服务能力&#xff0c;实现更高水平的应用容错&#xff1b; 根据不同的业务、访问需求和预设策略&…

Kafka之Consumer原理

1. Kafka消息消费流程 kafka的消费流程&#xff0c;首先是producer生产消息经过处理后放入到Broker服务器中&#xff0c;然后进入到内存中&#xff0c;内存再进行刷盘到磁盘中&#xff0c;kafak提供了两种刷盘策略&#xff0c;同步刷盘(flush.message 一次IO刷盘多少消息)和异…

PTA字符串删除

已知del_str为字符串str中要删除的子串&#xff0c;请结合所学字符串操作实现在str中删除所有del_str子串&#xff0c;并统计del_str在str中出现的次数。 输入格式: 123dufvdfv123dfljvb 123 输出格式: dufvdfvdfljvb #include<stdio.h> #include<string.h> in…

SSM物流管理系统的设计与实现-计算机毕业设计源码44323

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

Java编程常见问题汇总一

系列文章目录 文章目录 系列文章目录前言一、字符串连接误用二、错误的使用StringBuffer三、测试字符串相等性四、数字转换成字符串五、利用不可变对象(Immutable) 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分…

企业数字化转型的测度难题:基于大语言模型的新方法与新发现

《经济研究》新文章《企业数字化转型的测度难题&#xff1a;基于大语言模型的新方法与新发现》运用机器学习和大语言模型构造一套新的企业数字化转型指标。理论分析和数据交叉验证均表明&#xff0c;构建的指标相对已有方法更准确&#xff1a; 1.第一步&#xff1a;选择“管理…

45.自定义线程池(三)-拒绝策略

拒绝策略采用函数式接口参数传入&#xff0c;策略模式 FunctionalInterface public interface RejectPolicy<T> {void reject(BlockingQueue<T> queue, T task); } package com.xkj.thread.pool;import com.aspose.words.Run; import lombok.extern.slf4j.Slf4j;…

拒绝服务攻击

文章目录 拒绝服务攻击概述拒绝服务攻击简介分布式拒绝服务攻击DDoS与DoS的关系拒绝服务攻击分类 剧毒包型拒绝服务攻击WinNuke攻击泪滴(Teardrop) 攻击Land 攻击Ping of death攻击循环攻击 风暴型拒绝服务攻击风暴型DoS攻击风暴型攻击用的分组直接风暴型DDoSPING风暴攻击(直接…

03_03_初识SpringAOP和应用

一、SpringAOP的初识与原理 1、概述 AOP&#xff1a;面向切面编程OOP&#xff1a;面向对象编程面相切面编程&#xff1a;是基于OOP基础之上的新编程思想&#xff0c;OOP面向的主要是对象是类&#xff0c;而AOP面向的主要对象是切面&#xff0c;它在处理日志、安全管理、事务管…