Vue.js实现可编辑表格并高亮修改的单元格

news/2024/7/24 13:32:07 标签: vue.js, elementui

实现一个可编辑的表格,让用户可以修改表格中的数据,并且能够清楚地看到哪些单元格被修改过。这样的功能可以提高用户体验,也方便后端处理数据的变化。

本文将介绍如何使用Vue.js和Element UI的el-table组件来实现一个可编辑表格,并且修改的单元格会有不同的背景色。
在这里插入图片描述

代码实现

首先创建一个el-table组件,给它绑定一个data属性,用来存储表格的数据。给每个el-table-column设置一个prop属性,用来指定每一列对应的数据字段。使用v-for指令来动态生成表格的列,根据一个tableColumn数组,里面存储了每一列的信息,比如label,prop,fixed等。可以给el-table添加一些事件监听,比如cell-mouse-enter,cell-mouse-leave,cell-click等,用来实现鼠标移入移出和点击单元格的效果。代码如下:

<el-table ref="multipleTable"  stripe :border=true :data="tableData"
            @cell-mouse-enter="handleCellEnter" @cell-mouse-leave="handleCellLeave" @cell-click="handleCellClick"
            :cell-style="cellstyle">
            <el-table-column width=120 v-for="column in tableColumn" :key="column.aliasColName"
              :prop="column.aliasColName" :label="column.text" :fixed="column.fixed">
              <div class="item" v-if="column.editStyle == 5"
                slot-scope="scope">
                <el-input class="item__input"  v-model="scope.row[scope.column.property]" placeholder="请输入内容">
               <i slot="suffix" class="el-icon-edit" @click="showPwd(scope.row, scope.$index, scope.column)"></i>
                </el-input>
                <div class="item__txt">{{ scope.row[scope.column.property] }}</div>
              </div>
              <div class="item" v-else-if="column.editStyle == 22" slot-scope="scope">
                <el-select v-model="scope.row[scope.column.property]" placeholder="请选择">
                  <el-option v-for="item in listArray" :key="item.value" :label="item.display" :value="item.value">
                  </el-option>
                </el-select>
              </div>
            </el-table-column>
            <el-table-column fixed="right" label="操作" width="120" v-if="!visremove">
              <div class="item" slot-scope="scope">
                <el-popconfirm confirm-button-text='好的' cancel-button-text='取消' icon="el-icon-info" icon-color="red"
                  title="确定删除吗?" @confirm="removerow(scope.row)">
                  <el-button slot="reference" type="text" size="small">删除</el-button>
                </el-popconfirm>
              </div>
            </el-table-column>
          </el-table>

接下来需要在data中定义一些变量,用来存储表格的数据,列的信息,下拉框的选项,以及一些控制变量,比如clickSwitch,用来记录当前点击的单元格,clickCellMap,用来存储当前点击的单元格的DOM元素,tableDataCopy,用来存储表格数据的副本,用于和修改后的数据进行对比。代码如下:

data() {
      return {
        tableData: [], //表格数据
        tableColumn: [], //表格列信息
        listArray: [], //下拉框选项
        clickSwitch: { //当前点击的单元格
          row: "",
          col: ""
        },
        clickCellMap: [], //当前点击的单元格的DOM元素
        tableDataCopy: [], //表格数据的副本
      };
    },

然后,需要在mounted中调用一个loadtabledata方法,用来加载表格的数据和列的信息。这里使用了一个模拟的数据文件loadData.json,里面存储了表格的数据和列的信息。根据实际的需求,从后端获取数据或者自定义数据。还需要使用JSON.parse和JSON.stringify方法,来创建一个表格数据的副本,用于后续的对比。代码如下:

mounted() {
      this.loadtabledata();
    },
    methods: {
      //表格
      loadtabledata() {
        let resloadtabledata = require("@/artificialdata/loadData.json")
        this.tableData = resloadtabledata.data.data
        this.tableDataCopy = JSON.parse(JSON.stringify(resloadtabledata.data.data))
      },
    }

接下来实现一些事件处理的方法,用来实现鼠标移入移出和点击单元格的效果。handleCellEnter方法用来处理鼠标移入单元格的事件。获取当前单元格的column和cell,然后判断是否有prop属性,如果有,说明是可编辑的单元格,就给它的item__txt类添加一个item__txt–hover类,用来显示一个编辑图标,提示用户可以点击编辑。代码如下:

/** 鼠标移入cell */
    handleCellEnter(row, column, cell, event) {
      const property = column.property
      if (property) {
        cell.querySelector('.item__txt').classList.add('item__txt--hover')
      }
    },

然后,需要实现一个handleCellLeave方法,用来处理鼠标移出单元格的事件。需要获取当前单元格的column和cell,然后判断是否有prop属性,如果有,说明是可编辑的单元格,就给它的item__txt类移除一个item__txt–hover类,用来隐藏编辑图标。代码如下:

/** 鼠标移出cell */
    handleCellLeave(row, column, cell, event) {
      const property = column.property
      if (property) {
        cell.querySelector('.item__txt').classList.remove('item__txt--hover')
      }
    },

接下来,实现一个handleCellClick方法,用来处理点击单元格的事件。获取当前单元格的row,column,cell,然后判断是否是同一个单元格,如果是,就不做任何操作,如果不是,就记录当前点击的单元格的信息,存储到clickSwitch变量中。然后,需要判断是否有之前点击的单元格,如果有,就触发它的失焦事件,让它保存数据,并且切换它的显示状态,让它显示文本,隐藏输入框。最后,切换当前点击的单元格的显示状态,让它显示输入框,隐藏文本,并且让输入框获取焦点。代码如下:

/** 点击cell */
    handleCellClick(row, column, cell, event) {
      if (this.clickSwitch.row == row.id && this.clickSwitch.col == column.property) {
        return
      }
      this.clickSwitch.row = row.id
      this.clickSwitch.col = column.property

      const property = column.property
      // 保存cell
      if (this.clickCellMap.length > 0 ) {
        this.clickCellMap[0].querySelector('input').blur()
      }
      if (this.clickCellMap.length > 0) {
        this.clickCellMap[0].querySelector('.item__txt').style.display = 'block'
        this.clickCellMap[0].querySelector('.item__input').style.display = 'none'
      }
     
        this.clickCellMap[0]=cell
        cell.querySelector('.item__txt').style.display = 'none'
        cell.querySelector('.item__input').style.display = 'block'
        cell.querySelector('input').focus()
      
    },

最后实现一个cellstyle方法,用来设置单元格的样式。需要获取当前单元格的row,column,rowIndex,columnIndex,然后判断当前单元格的值是否和表格数据副本中的值相同,如果不同,就说明该单元格被修改过,就给它返回一个背景色的样式,比如"background-color: rgb(144 199 255);",让它显示为蓝色。这样,用户就可以一眼看出哪些单元格被修改过,哪些没有。代码如下:

cellstyle({ row, column, rowIndex, columnIndex }) {
      if (this.tableDataCopy[rowIndex][column.property] != row[column.property]) {
        return "background-color: rgb(144 199 255);"
      }
    },

效果展示

表格中有两种类型的可编辑单元格,一种是输入框,一种是下拉框。当鼠标移入一个可编辑的单元格时,它会显示一个编辑图标,提示可以点击编辑。当点击一个可编辑的单元格时,它会显示一个输入框或者下拉框修改数据。当修改完数据后,按下回车键或者点击其他地方,它会保存数据,并且切换回文本显示。同时可以看到,修改过的单元格会有一个蓝色的背景色,清楚地看到数据的变化。还可以点击右侧的删除按钮,删除一行数据。代码如下:

cellstyle({ row, column, rowIndex, columnIndex }) {
      if (this.tableDataCopy[rowIndex][column.property] != row[column.property]) {
        return "background-color: rgb(144 199 255);"
      }
    },

在这里插入图片描述
在这里插入图片描述

.el-input__icon {
  line-height: 24px !important;
}

.el-button--text {
  height: 24px;

}

.item {
  .el-input--suffix .el-input__inner {
    padding-right: 20px;
    padding-left: 10px;
  }

  .el-input__inner {
    height: 24px !important;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }

  .item__input {
    display: none;
  }

  .item__txt {
    box-sizing: border-box;
    border: 1px solid transparent;
    width: 100px;
    line-height: 24px;
    padding: 0 8px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }

  .item__txt--hover {
    border: 1px solid #dddddd;
    border-radius: 4px;
    cursor: text;
  }
}
.el-table {
  .el-table__cell {
    padding: 6px 0 !important;
  }

}

http://www.niftyadmin.cn/n/5244763.html

相关文章

如何提升企业的工作效率?

随着科技的迅速发展&#xff0c;企业已基本向信息化转型&#xff0c;电脑已经成为企业办公不可或缺的工具。员工整体的工作效率&#xff0c;直接影响着企业的盈利能力和竞争力。如何提升企业的工作效率&#xff1f; 1. 流程优化 分析并优化生产流程&#xff0c;消除冗余和浪费…

剧本杀小程序搭建:打造线上剧本杀新体验

剧本杀是一款以角色扮演为主的游戏&#xff0c;一度成为了年轻人的最喜爱的社交游戏。在剧本杀市场需求下&#xff0c;剧本杀规模也迅速上升。今年第一季度&#xff0c;剧本杀市场规模环比增长47%&#xff0c;市场整体消费水平逐渐呈上升趋势。 随着剧本杀的不断发展&#xff…

深度学习实战64-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍

大家好,我是微学AI,今天给大家介绍一下深度学习实战64-人脸检测模型LFFD的搭建,LFFD模型的架构与原理的详细介绍。LFFD(Light and Fast Face Detector)模型是一种用于人脸检测的深度学习模型,其设计旨在实现轻量级和快速的人脸检测。本文将详细介绍LFFD模型的定义、优点、原…

【flink番外篇】1、flink的23种常用算子介绍及详细示例(2)- keyby、reduce和Aggregations

Flink 系列文章 1、Flink 专栏等系列综合文章链接 文章目录 Flink 系列文章一、Flink的23种算子说明及示例6、KeyBy7、Reduce8、Aggregations 本文主要介绍Flink 的3种常用的operator&#xff08;keyby、reduce和Aggregations&#xff09;及以具体可运行示例进行说明. 如果需要…

Django之admin后台页面功能详解

一&#xff09;对于admin的初了解 1.简介 Django是一种流行的Python Web开发框架&#xff0c;它提供了一个功能强大且易于使用的admin界面&#xff0c;用于管理网站的后台数据和功能。Django的admin界面是自动生成的&#xff0c;它根据你的模型类自动创建表单和列表视图。你只…

JavaScript基础(23)_DOM增删改

DOM增加对象 createElement(): 含义&#xff1a;创建一个元素节点对象。 用法&#xff1a;它需要一个标签名作为参数&#xff0c;将会根据该标签名创建元素节点对象&#xff0c;并将创建好的对象作为返回值返回。比如&#xff1a;var li document.createElement("li&quo…

使用postman请求x5接口

x5接口简介 1.接口样例 {"header"{"appid":"bpmnew_fanwei","sign":"C033162E86E4CADE80C7EB44D68A5AD2","sign_type":"md5","url":"https://oa.mioffice.cn/api/bpm/xm/app/show/tod…

数据结构初阶之二叉树的详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 Linux 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力,共赴大厂。 目录 1.前言 2.二叉树各个…