element-ui:el-table合并单元格后的行高亮显示

简介: element-ui:el-table合并单元格后的行高亮显示

有如下一份数据

src/data.json

{
  "list": [
    {
      "id": 1,
      "user_id": 1,
      "name": "王小虎",
      "address": "上海市普陀区金沙江路 1 弄"
    },
    {
      "id": 2,
      "user_id": 1,
      "name": "王小虎",
      "address": "上海市普陀区金沙江路 2 弄"
    },
    {
      "id": 3,
      "user_id": 1,
      "name": "王小虎",
      "address": "上海市普陀区金沙江路 3 弄"
    },
    {
      "id": 4,
      "user_id": 2,
      "name": "张大彪",
      "address": "北京市朝阳区建国路360号"
    },
    {
      "id": 5,
      "user_id": 3,
      "name": "刘大龙",
      "address": "深圳市福田区滨河路路1号"
    },
    {
      "id": 6,
      "user_id": 3,
      "name": "刘大龙",
      "address": "深圳市福田区滨河路路2号"
    }
  ],
  "total": 6
}

完整数据默认显示如下

image.png


需求

需要按照合并相同用户的名字列(user_id)显示到表格中


方案:


通过el-table 所提供的参数,可以设置span-method 属性,来控制列或行的合并

合并后,发现鼠标经过某一单元格后,并没有按照所期待的那样,整个行数据都有背景色显示

image.png

我们还需要对单元格的样式进行处理

当鼠标经过某一行时,需要把已合并的这几行都设置相同的背景颜色,

通过参考其他文章,发现实现方案代码都不完整,或者不能实现相应的效果

于是,采用:事件监听 + jqeury 的实现方案,思路:

通过el-table 提供事件监听方法:鼠标移入单元格@cell-mouse-enter ,鼠标移出单元格@cell-mouse-leave

当鼠标移入某个单元格时,将需要高亮的行通过jquery动态添加自定义类名,实现高亮

当鼠标移出单元格时,通过jquery 将所有的行都去除高亮类名,实现重置显示状态

最终实现的效果

image.png

完整代码

$ tree -I node_modules
.
├── package.json
├── pnpm-lock.yaml
└── src
    ├── App.vue
    ├── data.json
    └── main.js

package.json

{
  "scripts": {
    "serve": "vue-cli-service serve --open",
    "build": "vue-cli-service build"
  },
  "devDependencies": {
    "@vue/cli": "^5.0.4",
    "@vue/cli-service": "^5.0.4",
    "css-loader": "^6.7.1",
    "less": "^4.1.2",
    "less-loader": "^11.0.0",
    "style-loader": "^3.3.1",
    "vue-template-compiler": "^2.6.14"
  },
  "dependencies": {
    "element-ui": "^2.15.8",
    "jquery": "^3.6.0",
    "vue": "2"
  }
}

src/main.js

import Vue from "vue";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import App from "./App.vue";
Vue.use(ElementUI);
new Vue({
  el: "#app",
  render: (h) => h(App),
});

src/App.vue

<template>
  <div class="">
    <!-- 自定义行和单元格的样式类,用于选择器操作 -->
    <el-table :data="list"
      border
      :span-method="objectSpanMethod"
      row-class-name="mo-table__row"
      cell-class-name="mo-table__cell"
      @cell-mouse-enter="handleCellMouseEnter"
      @cell-mouse-leave="handleCellMouseLeave">
      <el-table-column width="80"
        align="center"
        header-align="center"
        prop="user_id"
        label="用户ID">
      </el-table-column>
      <el-table-column prop="name"
        label="姓名"
        header-align="center"
        width="180">
      </el-table-column>
      <el-table-column prop="address"
        label="地址"
        header-align="center">
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
// created at 2022-06-02
import data from './data.json';
import $ from 'jquery';
export default {
  name: 'App',
  props: {},
  components: {},
  data() {
    return {
      list: [],
      // 记录当前高亮的行
      highlight_rows: [],
    };
  },
  computed: {},
  methods: {
    // 初始化数据
    getData() {
      // 统计每个用户的地址数量
      let user_address_count_map = {};
      for (let item of data.list) {
        let user_address_count = user_address_count_map[item.user_id] || 0;
        user_address_count_map[item.user_id] = user_address_count + 1;
      }
      // 记录当前行
      let current_item = {};
      this.list = data.list.map((item, index) => {
        // 添加一个行号,用于记录高亮的行
        item.row_index = index;
        // 是否为用户地址的第一条数据,决定开始合并的起始行
        item.is_user_address_first_row =
          item.user_id != current_item.user_id ? true : false;
        // 用户地址的数量,决定合并的行数
        item.user_address_count = user_address_count_map[item.user_id];
        current_item = item;
        return item;
      });
      // console.log(this.list);
    },
    // 合并单元格
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // console.log(row, column);
      // id和 name列合并
      if (['user_id', 'name'].includes(column.property)) {
        // 每个用户的地址首行合并
        if (row.is_user_address_first_row) {
          return {
            rowspan: row.user_address_count,
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }
    },
    // 当单元格 hover 进入时会触发该事件
    handleCellMouseEnter(row, column, cell, event) {
      // 将所有user_id相同的行都放入高亮数组
      for (let item of this.list) {
        if (row.user_id == item.user_id) {
          this.highlight_rows.push(item);
          // $(event.target).css('background-color', '#f5f5f5');
        }
      }
      this.setTableRowHighlight();
    },
    // 当单元格 hover 退出时会触发该事件
    handleCellMouseLeave(row, column, cell, event) {
      this.highlight_rows.splice(0, this.highlight_rows.length);
      this.resetTableRowHighlight();
    },
    resetTableRowHighlight() {
      // 移除所有高亮行的高亮样式
      $('.mo-table__row').removeClass('mo-table__row--active');
    },
    setTableRowHighlight() {
      // 重新添加高亮行的高亮样式
      for (let item of this.highlight_rows) {
        // 通过预先定义的行号来选中要高亮的行
        let selector = `.mo-table__row:nth-child(${item.row_index + 1})`;
        $(selector).addClass('mo-table__row--active');
      }
    },
  },
  created() {
    this.getData();
  },
};
</script>
<style lang="less">
// 行的样式
.mo-table__row {
}
// 单元格的样式
.mo-table__cell {
}
// 去除element-ui 默认的鼠标移入样式
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
  background-color: transparent;
}
// 自定义的高亮样式
.el-table--enable-row-hover .el-table__body .mo-table__row--active {
  background-color: #f5f7fa;
}
</style>
<style lang="less" scoped>
</style>

不得不说,那么多年过去了,jquery 还是那么经久不衰,简单实用


当然,此处也可以将jquery 替换为document.querySelector 方法


参考

https://element.eleme.io/#/zh-CN/component/table

https://jquery.cuishifeng.cn/index.html


相关文章
|
7月前
有关element UI el-table 跟el-dialog搭配使用出现的问题,背景问题,穿透问题
有关element UI el-table 跟el-dialog搭配使用出现的问题,背景问题,穿透问题
345 0
|
前端开发
element ui el-table 多选 表头全选框替换文字
element ui el-table 多选 表头全选框替换文字
1663 0
|
JavaScript
element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示
问题原因:多个tabs共用一个实体,动态显示隐藏列 出现了固定在右侧的列(fixed="right")错位 【解决方案】 表格的重新布局,只要table数据发生变化的时候就重新渲染表格 ```js this.$nextTick(() => { this.$refs.formname.doLayout() }) ``` 参考element官方文档 ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/column/article/5877188/20231030-e40
286 0
element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示
|
4月前
|
JavaScript 开发者
Element UI & Element Plus之改变表格单元格颜色
这篇文章展示了如何在Element UI和Element Plus框架中使用`:cell-style`属性来根据条件改变表格单元格的颜色。
461 0
Element UI & Element Plus之改变表格单元格颜色
|
5月前
Element UI 【表格合计】el-table 实战范例 -- 添加单位,自定义计算逻辑
Element UI 【表格合计】el-table 实战范例 -- 添加单位,自定义计算逻辑
476 0
|
5月前
|
JavaScript
vue项目中升级element ui(含常见报错及解决方案,如表格不显示,el-table无效, “__v_isRef“ is not defined,Use :deep() instead)
vue项目中升级element ui(含常见报错及解决方案,如表格不显示,el-table无效, “__v_isRef“ is not defined,Use :deep() instead)
74 0
|
7月前
基于sortablejs实现拖拽element-ui el-table表格行进行排序
基于sortablejs实现拖拽element-ui el-table表格行进行排序
Element-ui 表格 (Table) 组件中动态合并单元格
Element-ui 表格 (Table) 组件中动态合并单元格
1038 0
Element-ui 表格 (Table) 组件中动态合并单元格
|
7月前
详解element-ui el-table表格中勾选checkbox(selection),高亮当前行高亮某一行(某一行设置特殊的样式)
详解element-ui el-table表格中勾选checkbox(selection),高亮当前行高亮某一行(某一行设置特殊的样式)
element-ui里的el-table在grid布局下切换数据有滚动条时不断增加?
element-ui里的el-table在grid布局下切换数据有滚动条时不断增加?
122 0