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

背景

数据为数组包对象,对象里面有属性值是数组;无需处理数据,直接使用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>

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

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

相关文章

酒店客房管理系统设计与实现(代码+数据库+文档)

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目 希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;一、研究背景 1.1 研究背景 当…

JKD的组成、Java跨平台、Path环境变量设置

一、JDK的组成 JVM&#xff1a;Java虚拟机&#xff0c;真正运行Java的地方 核心类库&#xff1a;Java自己写好的程序&#xff0c;给程序员自己调用 JRE&#xff1a;Java的运行环境&#xff0c;包含JVM和核心类库 JDK也就是Java开发工具&#xff0c;包含以上所有 二、Java的…

uniapp 开发小程序的时候使用自定义 tabbar 时出现切换页面闪烁的情况

问题&#xff1a;在使用自定义组件的时候可以看到页面切换明显的闪烁, 这种体验是很不好的, 当然最好的方式就是使用原生导航栏, 不要搞花里胡哨的东西。 来看下体验不好的效果 优化调整 先说思路&#xff0c;就是仍然设置原生 tabbar, 在应用启动的时候主动隐藏原生 tabba…

四、Java中SpringBoot组件集成接入【Knife4j接口文档(swagger增强)】

四、Java中SpringBoot组件集成接入【Knife4j接口文档&#xff08;swagger增强&#xff09;】 1.Knife4j介绍2.maven依赖3.配置类4.常用注解使用1.实体类及属性&#xff08;ApiModel和ApiModelProperty&#xff09;2.控制类及方法&#xff08;Api、ApiOperation、ApiImplicitPar…

windows 调试rtmp协议遇到send时返回10054问题之分析

一、当send一个视频帧大小为138262 1个basic header字节 11个message header字节时&#xff0c;遇到send失败&#xff0c;返回10054 二、通过启动srs打印看出是超出范围了 总结就是数据超过了srs的数据接收范围

【Scala】——函数式编程

1 面向对象编程和函数式编程 1.1 面向对象编程 解决问题&#xff0c;分解对象&#xff0c;行为&#xff0c;属性&#xff0c;然后通过对象的关系以及行为的调用来解决问题。 • 对象&#xff1a;用户 • 行为&#xff1a;登录、连接 JDBC、读取数据库 • 属性&#xff1a;用户…

springboot2.7集成sharding-jdbc4.1.1实现业务分表

1、引入maven <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency> 2、基本代码示例 基本逻辑&#xff1a;利用数…

windows10+ubuntu20.04双系统中,ubuntu系统显示home空间不足的扩容方法

实际上网上有两种扩容方法&#xff0c;除了本文的方法外&#xff0c;另一种是在使用启动U盘打开试用ubuntu&#xff0c;应该涉及到nvidia显卡驱动问题故未采用。另一种即本文。 最开始安装双系统时内存分配没有分配好&#xff0c;给ubuntu系统分配的空间较小,导致了后来的的问…

vivado xsim 终端 模拟

只模拟的话直接终端运行会快很多 计数器举例 mkdir srccounter.v module counter(input wire clk,input wire rst_n,output reg[31:0] cnt ); always (posedge clk or negedge rst_n)if(!rst_n)cnt < 31h0;elsecnt < cnt1;endmodule tb.v module tb; wire[31:0] out…

Python - Bert-VITS2 自定义训练语音

目录 一.引言 二.前期准备 1.Conda 环境搭建 2.Bert 模型下载 3.预训练模型下载 三.数据准备 1.音频文件批量处理 2.训练文件地址生成 3.模型训练配置生成 4.训练文件重采样 5.Tensor pt 文件生成 四.模型训练 1.预训练模型 2.模型训练 3.模型收菜 五.总结 一…

基于模块自定义扩展字段的后端逻辑实现(二)

目录 一&#xff1a;创建表 二&#xff1a;代码逻辑 上一节我们详细讲解了自定义扩展字段的逻辑实现和表的设计&#xff0c;这一节我们以一个具体例子演示下&#xff0c;如何实现一个订单模块的自定义扩展数据。 一&#xff1a;创建表 订单主表: CREATE TABLE t_order ( …

流量主答题小程序源码系统:自定义题库或一键导入,采用PHP+MySQL 带完整的安装部署教程

随着互联网的发展&#xff0c;答题类小程序因其互动性强、用户粘性高等特点&#xff0c;受到了广泛的欢迎。小编来给大家分享一款流量主答题小程序源码系统。该系统采用PHPMySQL技术&#xff0c;功能强大且易于扩展&#xff0c;为开发者提供了一个完整的答题平台解决方案。 以…

【APP抓包】IOS应用抓包防护绕过实战教程

文章目录 1. 写在前面2. 测试机越狱2.1. 爱思助手2.2. checkra1n 3. 代理抓包3.1. 安装CA证书 4. 客户端证书绑定绕过4.1. SSLKillSwitch4.2. Objection 5. 双向证书绑定绕过5.1. 绕过服务端 6. 越狱检测绕过6.1. Liberty Lite绕过检测6.2. Hestia绕过检测6.3. HideJB绕过检测6…

智能化配网故障定位技术:未来发展趋势与应用前景

在当今这个科技高速发展的时代&#xff0c;智能化技术已经渗透到了我们生活的方方面面。作为电力行业的重要组成部分&#xff0c;配电网的自动化和智能化水平也在不断提高。本文将重点介绍一种基于成熟的行波测距技术的智能化配网故障定位技术——配网行波型故障预警与定位系统…

Vue3-watch的用法

watch简介 作用:监视数据的变化 (和 Vue2 中的 watch 作用一致) 特点: Vue3 中的 watch 只能监视以下四种数据 1.ref 定义的数据(又可以分 基本 和 对象 ) 2.reactive 定义的数据 3.函数返回一个值。(getter 函数) 4.一个包含上述内容的数组 我们在 Vue3 中使用 watch …

Zookeeper系列(一)集群搭建(非容器)

系列文章 Zookeeper系列&#xff08;一&#xff09;集群搭建&#xff08;非容器&#xff09; 目录 前言 下载 搭建 Data目录 Conf目录 集群复制和修改 启动 配置示例 测试 总结 前言 Zookeeper是一个开源的分布式协调服务&#xff0c;其设计目标是将那些复杂的且容易出错的分…

CHS_01.1.5+操作系统引导

CHS_01.1.5操作系统引导 操作系统的引导一个新的磁盘安装操作系统后操作系统引导&#xff08;开机过程&#xff09; 操作系统的引导 我们会学习操作系统的引导 那你可能看见这个词的时候会觉得莫名其妙不明 绝地 什么是操作系统的引导呢 简单来说就是当你在开机的时候 如何让…

apt和apt-get的区别

文章目录 环境问题背景区别进度条显示可更新包的数量upgrade 对比apt-get 过时了吗使用apt还是apt-get总结参考 环境 RHEL 9.3Docker Community 24.0.7Ubuntu Docker image jammy 22.04lunar 23.04 Ubuntu 22.04 问题 apt 和 apt-get 有一些相似之处。比如&#xff0c;如果想…

在VS Code中安装Copilot与安装其他扩展的方法一样,只需简单几步

GitHub Copilot是由OpenAI和GitHub开发的人工智能工具。它的目的是通过自动完成代码来帮助开发人员使用集成开发环境&#xff08;IDE&#xff09;&#xff0c;如Visual Studio Code。它目前仅作为技术预览版提供&#xff0c;因此只有在候补名单上被认可的用户才能访问它。对于用…

Spark避坑系列一(基础知识)

大家想了解更多大数据相关内容请移驾我的课堂: 大数据相关课程 剖析及实践企业级大数据 数据架构规划设计 大厂架构师知识梳理:剖析及实践数据建模 剖析及实践数据资产运营平台 Spark作为大数据领域离线计算的王者,在分布式数据处理计算领域有着极高的处理效率,而Python作为…