el-table实现多行合并的效果,并可编辑单元格

news2024/12/23 17:26:39

背景

数据为数组包对象,对象里面有属性值是数组;无需处理数据,直接使用el-table包el-table的方法,通过修改el-table的样式直接实现多行合并的效果 

html代码

<template>
    <div>
      <el-table size="mini" :data="tableData" v-loading="ruletableLoading" border style="width: 100%" height="calc(100% - 56px)" class="rule-table">
        <el-table-column label="AA" prop="code" show-overflow-tooltip>
          <template #default="scope">
            <!-- <div class="item"> -->
            <div class="cell-content item-normal" @click.stop="cellClick">
              <el-input size="small" class="item__input" v-model="scope.row.code" placeholder="请输入" @blur="handleBlur"></el-input>
              <div class="item__txt">{{ scope.row.code }}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="BB" prop="name" show-overflow-tooltip>
          <template #default="scope">
            <!-- <div class="item"> -->
            <div class="cell-content item-normal" @click.stop="cellClick">
              <el-input size="small" class="item__input" v-model="scope.row.name" placeholder="请输入" @blur="handleBlur"></el-input>
              <div class="item__txt">{{ scope.row.name }}</div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="CC">
          <template #default="scope">
            <el-table :data="scope.row.items" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="name" show-overflow-tooltip>
                <template #default="scope">
                  <!-- <div class="item"> -->
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.name" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.name }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column label="DD" width="120">
          <template #default="scope">
            <el-table :data="scope.row.items" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="percent" show-overflow-tooltip>
                <template #default="scope">
                  <!-- <div class="item"> -->
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.percent" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.percent }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>

        <el-table-column label="EE" width="120">
          <template #default="scope">
            <el-table :data="scope.row.items" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="score" show-overflow-tooltip>
                <template #default="scope">
                  <!-- <div class="item"> -->
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.score" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.score }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>

        <el-table-column label="FF" prop="totalScore" show-overflow-tooltip width="120">
          <template #default="scope">
            <!-- <div class="item"> -->
            <div class="cell-content item-normal" @click.stop="cellClick">
              <el-input size="small" class="item__input" v-model="scope.row.totalScore" placeholder="请输入" @blur="handleBlur"></el-input>
              <div class="item__txt">{{ scope.row.totalScore }}</div>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="GG">
          <template #default="scope">
            <el-table :data="scope.row.classStandard" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="express" show-overflow-tooltip>
                <template #default="scope">
                  <!-- <div class="item"> -->
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.express" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.express }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>

        <el-table-column label="HH">
          <template #default="scope">
            <el-table :data="scope.row.classStandard" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="class" show-overflow-tooltip>
                <template #default="scope">
                  <!-- <div class="item"> -->
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.class" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.class }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>

        <el-table-column label="II">
          <template #default="scope">
            <el-table :data="scope.row.classStandard" :border="false" :show-header="false" class="no-border-table">
              <el-table-column prop="remark" show-overflow-tooltip>
                <template #default="scope">
                  <div class="cell-content item-normal" @click.stop="cellClick">
                    <el-input size="small" class="item__input" v-model="scope.row.remark" placeholder="请输入" @blur="handleBlur"></el-input>
                    <div class="item__txt">{{ scope.row.remark }}</div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
      </el-table>

    </div>
  </template>

js代码 

主要是cellClick和handleBlur控制的,首先需要找到包裹el-input和展示表格文字的父div,然后通过点击父div和el-input的失去焦点事件控制内部这两个元素的显示和隐藏

<script setup>
import { ref, computed,onMounted } from 'vue'
import ruletableDataJson from './ruleManage.json'
import { cloneDeep } from 'lodash'



const tableData=ref([])

onMounted(()=>{
  tableData.value=[
  {
    "id": 9090,
    "code": "1",
    "name": "密码和车好多看",
    "remark": "",
    "items": [
      {
        "id": 6767,
        "name": "合适的客户收款",       
        "percent": 0.7,   
        "score": 100 
      },
      {
        "id": 89808,
        "name": "附近的看法好的",       
        "percent": 0.3,    
        "score": 67 
      }
    ],
    "classStandard": [
      {
        "express": "年卡就诊卡",
        "remark": "活动开始计划的卡号",
        "class": "打开了电视机了"
      },
      {
        "express": "手机多少空间",
        "remark": "简单说来就是了",
        "class": "的"
      },
      {
        "express": "的角度来讲罗迪克",
        "remark": "十九岁的离开拘留所",
        "class": "对手的实力的距离"
      },
      {
        "express": "但是肯定是咯",
        "remark": "发达的",
        "class": "人工费v1"
      },
      {
        "express": "的快捷键",
        "remark": "附近的垃圾分类",
        "class": "分隔符"
      },
      {
        "express": "三大三",
        "remark": "反对反对开始",
        "class": "对顶的"
      },
      {
        "express": "多睡的",
        "remark": "对顶的",
        "class": "对对对对"
      },
      {
        "express": "对顶的",
        "remark": "的舒适性",
        "class": "多睡的"
      },
      {
        "express": "是啥",
        "remark": "都是大客户",
        "class": "山东江苏科技"
      }

    ]
  },
  {
    "id": 9090,
    "code": "2",
    "name": "密码和车好多看",
    "remark": "",
    "items": [
      {
        "id": 6767,
        "name": "合适的客户收款",       
        "percent": 0.7,   
        "score": 100 
      },
      {
        "id": 89808,
        "name": "附近的看法好的",       
        "percent": 0.3,    
        "score": 67 
      }
    ],
    "classStandard": [
      {
        "express": "年卡就诊卡",
        "remark": "活动开始计划的卡号",
        "class": "打开了电视机了"
      },
      {
        "express": "手机多少空间",
        "remark": "简单说来就是了",
        "class": "的"
      },
      {
        "express": "的角度来讲罗迪克",
        "remark": "十九岁的离开拘留所",
        "class": "对手的实力的距离"
      },
      {
        "express": "但是肯定是咯",
        "remark": "发达的",
        "class": "人工费v1"
      },
      {
        "express": "的快捷键",
        "remark": "附近的垃圾分类",
        "class": "分隔符"
      },
      {
        "express": "三大三",
        "remark": "反对反对开始",
        "class": "对顶的"
      },
      {
        "express": "多睡的",
        "remark": "对顶的",
        "class": "对对对对"
      },
      {
        "express": "对顶的",
        "remark": "的舒适性",
        "class": "多睡的"
      },
      {
        "express": "是啥",
        "remark": "都是大客户",
        "class": "山东江苏科技"
      }

    ]
  },
  {
    "id": 9090,
    "code": "3",
    "name": "密码和车好多看",
    "remark": "",
    "items": [
      {
        "id": 6767,
        "name": "合适的客户收款",       
        "percent": 0.7,   
        "score": 100 
      },
      {
        "id": 89808,
        "name": "附近的看法好的",       
        "percent": 0.3,    
        "score": 67 
      }
    ],
    "classStandard": [
      {
        "express": "年卡就诊卡",
        "remark": "活动开始计划的卡号",
        "class": "打开了电视机了"
      },
      {
        "express": "手机多少空间",
        "remark": "简单说来就是了",
        "class": "的"
      },
      {
        "express": "的角度来讲罗迪克",
        "remark": "十九岁的离开拘留所",
        "class": "对手的实力的距离"
      },
      {
        "express": "但是肯定是咯",
        "remark": "发达的",
        "class": "人工费v1"
      },
      {
        "express": "的快捷键",
        "remark": "附近的垃圾分类",
        "class": "分隔符"
      },
      {
        "express": "三大三",
        "remark": "反对反对开始",
        "class": "对顶的"
      },
      {
        "express": "多睡的",
        "remark": "对顶的",
        "class": "对对对对"
      },
      {
        "express": "对顶的",
        "remark": "的舒适性",
        "class": "多睡的"
      },
      {
        "express": "是啥",
        "remark": "都是大客户",
        "class": "山东江苏科技"
      }

    ]
  },
  ]
})

const cellClick = e => {
  let element = e.target.parentNode
  element.classList.remove('item-normal')
  element.classList.add('item-edit')
}

const handleBlur = e => {
  let element = e.target.parentNode.parentNode
  element.classList.remove('item-edit')
  element.classList.add('item-normal')
  dotShow.value=true
}
</script>

scss样式

首先设置cell-content的基础样式;元素饿显示和隐藏就单独拿出来通过在事件中做切换


  <style lang='scss' scoped>

// 对elementplus的样式修改

    .rule-table:deep() .cell {
  padding-left: 0px;
  padding-right: 0px;
}

:deep(.el-table--border) {
  border: none;
}

.rule-table .no-border-table :deep()tr:last-child td {
  border-bottom: none;
}

:deep().el-table::before {
  width: 0%;
  height: 0px;
}
.rule-table .no-border-table :deep()th {
  border-right: none;
}
.rule-table .no-border-table :deep()td {
  border-right: none;
}



// 可编辑

.cell-content {
  cursor: pointer;
  .item__input {
    // display: none;
    width: 95%;
    /* 调整elementUI中样式 如果不需要调整请忽略 */
    .el-input__inner {
      height: 24px !important;
    }
    /* 调整elementUI中样式 如果不需要调整请忽略 */
    .el-input__suffix {
      i {
        font-size: 12px !important;
        line-height: 26px !important;
      }
    }
  }
  .item__txt {
    // display: block;
    box-sizing: border-box;
    line-height: 32px;
    padding: 0 9px;
  }
}
// 单独设置编辑状态和常规状态
.item-edit {
  .item__input {
    display: block;
  }
  .item__txt {
    display: none;
  }
}
.item-normal {
  .item__input {
    display: none;
  }
  .item__txt {
    display: block;
  }
}

  </style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础知识:整理9 文件的相关操作

1 文件的打开 # open() 函数打开文件 # open(name, mode, encoding) """name: 文件名&#xff08;可以包含文件所在的具体路径&#xff09;mode: 文件打开模式encoding: 可选参数&#xff0c;表示读取文件的编码格式 """ 2 文件的读取 文…

设计模式-规格模式

设计模式专栏 模式介绍模式特点应用场景规格模式和策略模式的区别和联系代码示例Java实现规格模式Python实现规格模式 规格模式在spring中的应用 模式介绍 规格模式&#xff08;Specification Pattern&#xff09;是一种行为设计模式&#xff0c;其目的是将业务规则封装成可重…

【笔记】书生·浦语大模型实战营——第三课(基于 InternLM 和 LangChain 搭建你的知识库)

【参考&#xff1a;tutorial/langchain at main InternLM/tutorial】 【参考&#xff1a;(3)基于 InternLM 和 LangChain 搭建你的知识库_哔哩哔哩_bilibili-【OpenMMLab】】 笔记 基础作业 这里需要等好几分钟才行 bug&#xff1a; 碰到pandas相关报错就卸载重装 输出文字…

【野火i.MX6ULL开发板】开发板连接网络(WiFi)与 SSH 登录、上电自动登录、设置静态IP、板子默认参数

0、前言 参考之前自己写的&#xff1a; http://t.csdnimg.cn/g60P8 参考资料&#xff1a; [野火]《Linux基础与应用开发实战指南——基于i.MX6ULL开发板》_20230323 从野火官网下载 参考博客&#xff1a; http://t.csdnimg.cn/8uh4O 参考官方文档&#xff1a; https://doc.…

【算法每日一练]-练习篇 #Tile Pattern #Swapping Puzzle # socks

目录 今日知识点&#xff1a; 二维前缀和 逆序对 袜子配对(感觉挺难的&#xff0c;又不知道说啥) Tile Pattern Swapping Puzzle socks Tile Pattern 331 题意&#xff1a;有一个10^9*10^9的方格。W表示白色方格&#xff0c;B表示黑色方格。每个(i,j)方的颜色由(i…

PowerDesigner简介以及简单使用

软件简介&#xff1a; PowerDesigner是Sybase公司开发的数据库设计工具&#xff0c;开发人员能搞利用PowerDesigner开发数据流程图、各数据模型如物理数据模型&#xff0c;可以分别从概念数据模型(Conceptual Data Model)和物理数据模型(Physical Data Model)两个层次对数据库…

一点一点,照亮你的美

一、实验要求 当鼠标点击屏幕时&#xff0c;随机出现大大小小的星星闪烁&#xff0c;犹如夜晚的星空 二、实验思路 设置图片的大小 设置事件&#xff08;当鼠标点一下&#xff0c;获取一张图片&#xff09; 设置图片的位置 设置鼠标的位置和图片的相对位置 设置随机大小 …

如何使用GaussDB创建脱敏策略(MASKING POLICY)

目录 一、前言 二、GaussDB中的脱敏策略 1、数据脱敏的定义 2、创建脱敏策略的语法说明 三、在GaussDB中如何创建数据脱敏策略(示例) 1、创建脱敏策略的一般步骤 2、GaussDB数据库中创建脱敏策略的完整示例 1&#xff09;开启安全策略开关&#xff0c;以初识用户omm登录…

这6个设计小白学习网站,海量免费学习教程!

划到最后“阅读原文”——领取工具包&#xff08;超过1000工具&#xff0c;免费素材网站分享和行业报告&#xff09; Hi&#xff0c;我是胡猛夫~&#xff0c;专注于分享各类价值网站、高效工具&#xff01; ​更多资源&#xff0c;更多内容&#xff0c;欢迎交流&#xff01;公…

Unity编辑器扩展(外挂)

每日一句:未来的样子藏在现在的努力里 目录 什么是编译器开发 C#特性[System.Serializable] 特殊目录 命名空间 /*检视器属性控制*/ //添加变量悬浮提示文字 //给数值设定范围&#xff08;最小0&#xff0c;最大150&#xff09; //指定输入框&#xff0c;拥有5行 //默认…

寄快递选哪个平台便宜?快递优惠券免费领取!

寄快递选哪个平台便宜&#xff1f;快递优惠券免费领取&#xff01; 对于市场来说&#xff0c;快递业是非常重要的一部分&#xff0c;它业既贯通市场流通消费投资出口的各环节&#xff0c;又关联一二三各产业。根据相关数据显示&#xff0c;我国的快递行业正呈现势如破竹的劲头&…

双位置继电器DLS-5/2TH 额定电压:110VDC 触点形式:7开3闭 柜内安装

系列型号&#xff1a; DLS-5/1电磁式双位置继电器; DLS-5/2电磁式双位置继电器; DLS-5/3电磁式双位置继电器; DLS-5/2G电磁式双位置继电器; DLS-5/3 220VDC双位置继电器 一、用途 1.1用途 DLS-5双位置继电器(以下简称产品)用于各种保护与自动控制系统中&#xff0c;作为切换…

x-cmd pkg | magick - 开源图像处理工具

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 magick 是由 ImageMagick 提供的一个功能强大且多功能的开源图像处理工具&#xff0c;可以灵活高效地处理图像文件&#xff0c;例如格式转换、图像大小调整、图像裁减、图像拼接、图像色彩校正和图像合成等常见的图像…

神州战神z7ra7重装教程

UEFI模式下装的系统&#xff0c;开机速度明显比Legacy模式下装的系统开机速度更快 关键点&#xff1a; ①.U盘格式必须为FAT32 ②.不可以使用ISO镜像制作UEFI安装U盘&#xff0c;而是使用微软官方的工具。 ③.开机BIOS设置&#xff0c;最好将Secure boot设置为Disabled&#xf…

[Kubernetes]8. K8s使用Helm部署mysql集群(主从数据库集群)

上一节讲解了K8s包管理工具Helm、使用Helm部署mongodb集群(主从数据库集群),这里来看看K8s使用Helm部署mysql集群(主从数据库集群) 一.Helm 搭建mysql集群 1.安装mysql不使用persistence(无本地存储) 无本地存储:当重启的时候,数据库消失 (1).打开官网的应用中心 打开应用中…

Linux内存管理:(六)页交换算法

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 引言 在Linux操作系统中&#x…

【AI】CycleGan对抗生成网络遥感影像生成地图效果测试

今天看到一个有趣的项目&#xff0c;CycleGan对抗生成网络把马生成成斑马&#xff0c;还有一个测试用例是用遥感影像生成平面地图的效果&#xff0c;效果如下图所示&#xff0c;我大学是遥感专业&#xff0c;看到遥感影像就触动了我的原神&#xff0c;于是原神启动&#xff0c;…

@Transactional 事务注解

第一、先简单介绍一下Spring事务的传播行为 所谓事务的传播行为是指&#xff0c;如果在开始当前事务之前&#xff0c;一个事务上下文已经存在&#xff0c;此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量&…

C++学习笔记——返回对象

一、返回对象 当我们说一个函数返回对象时&#xff0c;意味着该函数的返回值是一个对象。这种情况下&#xff0c;函数可以通过创建对象的副本、返回对象的引用或者返回对象的指针来实现。 返回对象的副本&#xff1a; 当一个函数返回对象的副本时&#xff0c;函数内部会创建一…

VSCode使用MinGW编译器,配置C/C++环境

目录 一、安装VSCode 二、安装MinGW编译器 1、配置环境变量 2、测试配置是否成功 三、配置VSCode 1、安装所需扩展 2、新建代码存放文件夹 3、添加配置文件 4、配置文件内容 &#xff08;1&#xff09;c_cpp_properties.json &#xff08;2&#xff09;launch.json …