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

文章目录

有如下一份数据,src/data.json,完整数据默认显示如下
element-ui:el-table合并单元格后的行高亮显示,需要按照合并相同用户的名字列(user_id)显示到表格中,方案:,合并后,发现鼠标经过某一单元格后,并没有按照所期待的那样,整个行数据都有背景色显示
element-ui:el-table合并单元格后的行高亮显示 我们还需要对单元格的样式进行处理,当鼠标经过某一行时,需要把已合并的这几行都设置相同的背景颜色,,通过参考其他文章,发现实现方案代码都不完整,或者不能实现相应的效果,于是,采用:事件监听 +
jqeury 的实现方案,思路:,最终实现的效果
element-ui:el-table合并单元格后的行高亮显示,package.json,src/main.js,src/App.vue,不得不说,那么多年过去了,
jquery 还是那么经久不衰,简单实用,

有如下一份数据

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
}

完整数据默认显示如下 element-ui:el-table合并单元格后的行高亮显示

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

方案:

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

合并后,发现鼠标经过某一单元格后,并没有按照所期待的那样,整个行数据都有背景色显示 element-ui:el-table合并单元格后的行高亮显示 我们还需要对单元格的样式进行处理

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

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

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

  • 通过el-table 提供事件监听方法:鼠标移入单元格@cell-mouse-enter ,鼠标移出单元格@cell-mouse-leave
  • 当鼠标移入某个单元格时,将需要高亮的行通过jquery动态添加自定义类名,实现高亮
  • 当鼠标移出单元格时,通过jquery 将所有的行都去除高亮类名,实现重置显示状态

最终实现的效果 element-ui:el-table合并单元格后的行高亮显示

$ 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 还是那么经久不衰,简单实用

参考 https://element.eleme.io/#/zh-CN/component/table https://jquery.cuishifeng.cn/index.html

© 版权声明

相关文章