在vue中通过js动态绘制table,并且合并连续相同内容的行,支持点击编辑单元格内容

首先是vue代码

<template>
  <div id="body-container"
       style="position: absolute">

    <div class="box-container">
      <div class="lsb-table-box" >
        <div class="table-container" id="lsb-table">
        </div>
      </div>
    </div>
  </div>

</template>

然后是js方法

/**
 * 渲染表格
 */
function tableRenderCs() {

    const data=[{
        "one": "测试1",
        "two": "测试2",
        "three": "测试3",
        "four": "测试4",
        "five": "测试5",
        "six": "测试6",
        "seven": "测试7",
        "eight": "测试8",
        "nine": "测试9"
    },{
        "one": "测试1",
        "two": "测试2",
        "three": "测试3",
        "four": "测试4",
        "five": "测试5",
        "six": "测试6",
        "seven": "测试7",
        "eight": "测试8",
        "nine": "测试9"
    },{
        "one": "测试1",
        "two": "测试2",
        "three": "测试3",
        "four": "测试4",
        "five": "测试5",
        "six": "测试6",
        "seven": "测试7",
        "eight": "测试8",
        "nine": "测试9"
    }]

    let html = '<table class="table-wj JZ-A" border="1" cellspacing="0">' +
        '<thead>' +
        '<tr>' +
        '<th rowspan="2" colspan="3">第一列</th>' +
        '<th rowspan="2" colspan="1" style="width: 50px;">第二列</th>' +
        '<th rowspan="2" colspan="1" style="width: 100px;">第三列</th>' +
        '<th rowspan="2" colspan="1" style="width: 50px;">第四列</th>' +
        '<th rowspan="2" colspan="1" style="width: 80px;">第五列</th>' +
        '<th rowspan="1" colspan="3">第六列</th>' +
        '</tr>' +
        '<tr>' +
        '<th colspan="1" style="width: 50px;">第六列的第一列</th>' +
        '<th colspan="1" style="width: 90px;">第六列的第二列</th>' +
        '</tr>' +
        '</thead>' +
        '<tbody>';

    for (let i = 0; i < data.length; i++) {
        const item = data[i];

        html +=
            `<tr>` +
            `<td>${item.one}</td>` +
            `<td>${item.two}</td>` +
            `<td>${item.three}</td>` +
            `<td>${item.four}</td>` +
            `<td>${item.five}</td>` +
            `<td>${item.six}</td>` +
            `<td>${item.seven}</td>` +
            `<td>${item.eight}</td>` +
            `<td>${item.nine}</td>` +
            `</tr>`;
    }

    html += '</tbody></table>';

    let _$ = $(".lsb-table-box .table-container");
    _$.append(html);

   //存储列名对应的字段值,方便后面计算
    let rowName = {
        '0': 'one',
        '1': 'two',
        '2': 'three',
        '3': 'four',
        '4': 'five',
        '5': 'six',
        '6': 'seven',
        '7': 'eight',
        '8': 'nine',
    }

    editInput(_$, data, "two", rowName);
    mergeColumns();	//调用动态合并行的方法
}

/**
 * 执行合并逻辑
 */
function mergeColumns() {
    let $table = $('table.table-wj');
    let $rows = $table.find('tbody tr');

	const numCols = $rows.eq(0).find('td').length;//考虑全部列
    //const numCols = Math.min(3, $rows.eq(0).find('td').length); // 仅考虑前三列

    // 遍历每列
    for (let col = 1; col <= numCols; col++) {
        let $currentColumn = $table.find(`td:nth-child(${col})`);
        let prevContent = null;
        let rowspan = 1;

        for (let i = 0; i < $currentColumn.length; i++) {
            let $currentCell = $($currentColumn[i]);
            let currentContent = $currentCell.text();

            if (currentContent === prevContent) {
                rowspan++;
                $currentCell.addClass('hidden');
            } else {
                if (rowspan > 1) {
                    $currentColumn.eq(i - rowspan).attr('rowspan', rowspan);
                }
                prevContent = currentContent;
                rowspan = 1;
            }
        }

        if (rowspan > 1) {
            $currentColumn.eq($currentColumn.length - rowspan).attr('rowspan', rowspan);
        }
    }

    // 清除被隐藏的单元格
    $table.find('.hidden').remove();
}

const numCols这里给出了两种合并表格的逻辑,第一个是只会对前三列执行合并逻辑,而第二个会对所有列执行合并逻辑。下面是两种逻辑的合并效果图。
在这里插入图片描述
在这里插入图片描述
接下来是使单元格可以被编辑,并且获取到编辑后的值,以及单元格位置

在上面的方法中调用即可
 	editInput(_$, data, "two", rowName);	 //这里的four是上面  `<td>${item.four}</td>` 对应的字段名,也就是列名
	mergeColumns();	//这里一定要注意先调用editInput方法再调用mergeColumns,不然获取编辑单元格的列索引会有问题

/**
 * 设置单元格可编辑
 * @param _$    表对象
 * @param data  表数据
 * @param fieldName 编辑后要获取的值对应的列名
 * @param rowName 列的索引与数据库字段相对应的集合
 */
function editInput(_$, data, fieldName, rowName) {
    // 获取所有表格单元格
    let cells = _$.find('td');

    // 为每个单元格添加点击事件
    cells.each(function (index) {
        let column = $(this).index();
        let row = $(this).closest('tr').index();

        let columnName = Object.keys(data[0])[column]; // 获取对应列的字段名

        $(this).data('columnName', columnName); // 存储列名为数据属性

        $(this).on('mousedown', function (event) {
            // 如果是鼠标右键点击,不进行操作
            if (event.which === 3) return;

            let $input = $(this).find('input'); // 检查单元格内是否已有输入框

            if ($input.length === 0) { // 如果没有输入框,则进行以下操作
                let currentValue = $(this).text();

                // 创建一个输入框元素,并将当前单元格内容设置为其值
                $input = $('<input type="text">');
                $input.val(currentValue);

                // 设置输入框的样式
                $input.css({
                    'background-color': 'transparent', // 设置背景色为透明
                    'color': 'white', // 设置文字颜色为白色
                    'border': 'none', // 移除边框
                    'outline': 'none', // 移除外边框
                });

                // 清空单元格并将输入框添加到单元格中
                $(this).empty().append($input);

                // 焦点定位到输入框
                $input.focus();

                // 阻止默认行为
                event.preventDefault();

                // 处理输入框失去焦点事件
                $input.on('blur', function () {
                    let newValue = $input.val();
                    
                   let valueName = rowName[column];  // 获取列索引对应的字段名称
                    let columnValue = data[row][fieldName]; // 获取对应字段的值

                    console.log('编辑后的内容:', newValue);
                    console.log('所在单元格位置:', '行:', row, '列:', column);
                    console.log('所在列字段名:', valueName);
                    console.log(fieldName + '列的值:', columnValue);
                    
					console.log(`更改了${fieldName}为${columnValue}的字段${valueName}的值为${newValue}`)
                    
                    $(this).parent('td').text(newValue);
                });
            }
        });
    });
}

实现效果如下,同时还获取了当前单元格所在行里面指定的某一列的数据内容(比如可以获取当前行的id,以此来给后端修改数据库中的数据),注意行是从表头下面开始的,行和列的下标都是从0开始
在这里插入图片描述

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

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

相关文章

final

final final关键字是最终的意思&#xff0c;可以修饰&#xff08;类、方法、变量&#xff09;修饰类&#xff1a;该类被称为最终类&#xff0c;特点是不能被继承了修饰方法&#xff1a;该方法被称为最终方法&#xff0c;特点是不能被重写了修饰变量&#xff1a;该变量只能被赋…

配置OSPF与BFD联动

组网需求 如图1所示&#xff0c;SwitchA、SwitchB和SwitchC之间运行OSPF&#xff0c;SwitchA和SwitchB之间的交换仅作透传功能。现在需要SwitchA和SwitchB能快速感应它们之间的链路状态&#xff0c;当链路SwitchA-SwitchB发生故障时&#xff0c;业务能快速切换到备份链路Switch…

springboot 集成 redis luttuce redisson ,单机 集群模式(根据不同环境读取不同环境的配置)

luttuce 和redisson配置过程中实际上是独立的&#xff0c;他们两个可以同时集成&#xff0c;但是没有直接相关关系&#xff0c;配置相对独立。 所以分为Lettuce 和 Redisson 两套配置 父pom <!-- Spring Data Redis --><dependency><groupId>org.springframe…

图像卷积操作

目录 一、互相关运算 二、卷积层 三、图像中目标的边缘检测 四、学习卷积核 五、特征映射和感受野 一、互相关运算 严格来说&#xff0c;卷积层是个错误的叫法&#xff0c;因为它所表达的运算其实是互相关运算&#xff08;cross-correlation&#xff09;&#xff0c;而不是…

hive企业级调优策略之数据倾斜

测试所用到的数据参考&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135080511 本教程的计算环境为Hive on MR。计算资源的调整主要包括Yarn和MR。 数据倾斜概述 数据倾斜问题&#xff0c;通常是指参与计算的数据分布不均&#xff0…

二叉搜索树第大K节点,剑指offer,力扣

目录 题目地址&#xff1a; 题目&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 难度分析&#xff1a; 审题目事例提示&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现&#xff1a; 代码补充&#xff1a; 代码实现&#xff08;非递归&…

C#中(, ||)与(, |)的区别

前言 在C#编程语言中&#xff0c;逻辑运算符用于组合和比较条件&#xff0c;以控制程序的流程和行为。在逻辑运算符中&#xff0c;有两对非常重要的运算符&#xff1a;&&和||、&和|。尽管它们看起来很相似&#xff0c;但其实它们有着不同的行为和使用场景。下面我们…

PWM实现蜂鸣器

tim4.h #ifndef __TIM4_H__ #define __TIM4_H__ #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_tim.h" void timer4_init();#endif tim4.c #include "tim4.h"void timer4_init() {// 1. 设置GPI…

实践代码教你学会 Metasploit 渗透攻击【Ubuntu版本】

文章目录 一. Metasploit 渗透工具二. 安装配置三. 模块讲解3.1 auxiliary-辅助模块3.2 exploit-渗透攻击模块3.3 payload-攻击荷载模块 四. 模拟攻击4.1 准备工作4.2 漏洞探测4.3 漏洞利用4.4 后渗透操作 一. Metasploit 渗透工具 Metasploit Framework(MSF)是一款开源安全漏洞…

盘帮帮微淘客公众号系统2.0-查券返利机器人、赶快行动起来吧,很好的赚钱机会!

本插件使用uniCloud开发&#xff0c;使用本插件默认您已知晓并了解uniCloud&#xff01; 插件下载地址&#xff1a;点击查看 盘帮帮微淘客公众号系统2.0&#xff0c;可以将你的微信公众号变成智能AI查券返利机器人、帮助网购者全网搜券找券&#xff0c;网购者只需将商品链接和…

【ranger】CDP环境 更新 ranger 权限策略会发生低概率丢失权限策略的解决方法

一、问题描述&#xff1a; 我们的 kafka 服务在更新&#xff08;添加&#xff09; ranger 权限时&#xff0c;会有极低的概率导致 MM2 同步服务报错&#xff0c;报错内容 Not Authorized。但是查看 ranger 权限是赋予的&#xff0c;并且很早配置的权限策略也会报错。 相关组件…

物流运输CRM:让日常工作有条不紊

很多物流行业的企业主都有这样的烦恼&#xff1a;客户来自各行各业&#xff0c;很难细分管理&#xff1b;业务量大庞大&#xff0c;工作很难细化&#xff1b;客户满意度低&#xff0c;缺乏售后跟踪......如果您也面临相同的问题&#xff0c;那么该让CRM管理系统登场啦&#xff…

低代码工作流,在业务场景下启动流程节点绑定的具体步骤与注意事项

在业务管理的场景下&#xff0c;存在先做了对应的数据管理&#xff0c;后续增加管理的规范度&#xff0c;“在业务数据变化时发起流程”的需求&#xff0c;那么这种情况下就需要在业务管理&#xff08;列表页、表单&#xff09;中发起流程&#xff0c;让业务模型使用流程配置&a…

【Python炫酷系列】一闪一闪亮星星,漫天都是小星星(完整代码)

文章目录 环境需求完整代码详细分析系列文章环境需求 python3.11.4及以上版本PyCharm Community Edition 2023.2.5pyinstaller6.2.0(可选,这个库用于打包,使程序没有python环境也可以运行,如果想发给好朋友的话需要这个库哦~)【注】 python环境搭建请见:https://want595.…

STM32_窗口看门狗

什么是窗口看门狗&#xff1f; 窗口看门狗用于监测单片机程序运行时效是否精准&#xff0c;主要检测软件异常&#xff0c;一般用于需要精准检测 程序运行时间的场合。 窗口看门狗的本质是一个能产生 系统复位信号 和 提前唤醒中断 的 6 位计数器 产生复位条件&#xff1a; 当…

Moonbeam生态项目分析 — — 跨链借贷协议Orbiter One

概览 Orbiter One是一个非托管的借贷协议和DeFi中心&#xff0c;专注于跨链互操作性。通过使用从借贷中赚取的ORB Token铸造的Intergactic Whiskers Brigade NFT&#xff0c;用户可以质押并获得额外奖励&#xff0c;借贷和跨链存款则可以在不离开Moonbeam的情况下无缝参与其他…

Web自动化框架中验证码识别处理全攻略,让测试更得心应手!

前言&#xff1a; 随着Web应用程序的不断发展&#xff0c;自动化测试已成为项目开发中必不可少的一环。然而&#xff0c;验证码的出现却经常会使自动化测试变得更具挑战性。为了解决这个问题&#xff0c;我们需要一种方法来自动识别和处理验证码&#xff0c;从而提高自动化测试…

AD20基础操作

1、编译检查项 需要重点检查的&#xff0c;设置为致命错误 点击Messages查看编译结果&#xff1a; 2、添加封装 快捷键M,选择X,Y移动选择对象 编辑偏移量后确定。 另一种快捷方式&#xff1a; CtrlD查看3D模型

【无标题“零元购”这个适应新时代的线上模式你应该要了解下】

不是XX买不起&#xff0c;而是XX更有性价比! 最近大家应该常听这句话&#xff0c;例如什么不是星X克买不起&#xff0c;而是瑞X更有性价比之类的话语。那么大家有认真思考下为什么这句话会在这个全民消费时代从大部分的国民口中流传出来吗&#xff1f; 根据2023.3.15的一篇中国…

Java操作windows系统功能(二)

Java可以通过调用Windows系统的API来操作Windows&#xff0c;实现一些基本的操作&#xff0c;例如打开、关闭窗口、创建文件夹、复制、删除文件等。 具体操作可以引入Java的java.awt和java.awt.event包&#xff0c;并使用java.awt.Desktop类来进行操作。 以下是一些常用的操作…