vue3 结合element-plus组件库使用table进行合并行

需求 比如:

image.png

个人查看element-plus文档,去结合使用 [链接](Table 表格 | Element Plus (element-plus.org))

element文档中有“合并行或列”的例子: 多行或多列共用一个数据时,可以合并行或列。

通过给 table 传入span-method方法可以实现合并行或列, 方法的参数是一个对象,里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组,第一个元素代表 rowspan,第二个元素代表 colspan。 也可以返回一个键名为 rowspan 和 colspan 的对象;

话不多说,上代码!

import type { TableColumnCtx } from 'element-plus';
//举例数据格式
const data = [
    {
        userName: "营业收费系统",
        value1: "中国农业银行",
        value2: "2022-03",
        detectionTime: "2022-03-04",
    },
    {
        userName: "营业收费系统",
        value1: "中国农业银行",
        value2: "2022-03",
        detectionTime: "2022-03-04",
    },
    {
        userName: "营业收费系统",
        value1: "中国农业银行",
        value2: "2022-03",
        detectionTime: "2022-03-04",
    },
    {
        userName: "营业收费系统",
        value1: "中国农业银行",
        value2: "2022-03",
        detectionTime: "2022-03-04",
    }
 ];
 
//需要判断的属性组
const spanProps = ['userName', 'detectionTime'];

let rowSpansMap = new Map(); //存需要开始合并的行号,向下合并多少行

/**
 * 根据列表数据得出需要合并的行
 * @param data 列表数据
 */
const spanPropGroup = (data: any) => {
  let oldRow: any = null; //需要合并的行
  rowSpansMap = new Map(); //重置Map

  oldRow = data[0]; //默认第0行为需要合并的行
  rowSpansMap.set(0, 1); //第0行,向下合并一行(其实就是自己单独一行)
  let spanRow = 0; //记录需要开始合并的行号
  for (let i = 1; i < data.length; i++) {
    const item = data[i];
    let isSame = true;
    //遍历需要判断的属性判断对应值是否全部相等
    for (let j = 0; j < spanProps.length; j++) {
      const prop = spanProps[j];
      //只要有一个属性值不相等则记录新的需要合并的行号
      if (item[prop] != oldRow[prop]) {
        oldRow = item;
        rowSpansMap.set(i, 1);
        spanRow = i;
        isSame = false;
        break;
      }
    }
    //如果所有属性值相同则所需要合并的行数+1
    if (isSame) {
      let span = rowSpansMap.get(spanRow);
      rowSpansMap.set(spanRow, span + 1);
    }
  }
};

const objectSpanMethod: any = ({ row, column, rowIndex, columnIndex }) => {
  //采样值1-5列所对应的行不需要合并
  if (columnIndex != 3 && columnIndex != 4) {
    //根据当前行号从map中获取开始合并的行根据当前行号从map中获取开始合并的行号,向下合并多少行
    const span = rowSpansMap.get(rowIndex);
    if (span != null) {
      return {
        rowspan: span, //向下合并span行
        colspan: 1,
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      };
    }
  }
};
//进行传递数据
spanPropGroup(data);
<template>
    <el-table
        :data="data"
        border
        :span-method="objectSpanMethod"
    >
        <el-table-column type="selection" width="55" />
        <el-table-column label="#" width="60" prop="">
            <template #default="{ $index }">
                {{ $index + 1 }}
            </template>
        </el-table-column>
        <el-table-column
            label="指标组合名称"
            align="center"
            prop="userName"
            show-overflow-tooltip
        />
        <el-table-column
            label="已使用使用指标"
            align="center"
            prop="value1"
            show-overflow-tooltip
        />
        <el-table-column
            label="权重"
            align="center"
            prop="value2"
            show-overflow-tooltip
        />
        <el-table-column
            label="计算状态"
            align="center"
            prop="detectionTime"
            show-overflow-tooltip
        /> 
        <el-table-column label="操作" width="160" resizable>
            <template #default="scope">
                <el-buttontype="text">删除</el-button>
            </template>
       </el-table-column>
    </el-table>
</template>

这样的效果就达到想要的需求了,细心观察一下代码!

### 修改 Element Plus 组件样式的解决方案 #### 使用 CSS 覆盖默认样式 为了自定义 Element Plus 组件的样式,可以直接通过全局或局部的方式覆盖其默认样式。对于 `el-table` 这样的组件来说,在项目中的公共样式文件中添加特定的选择器来调整表格外观是一个常见的做法[^1]。 ```css /* 在 main.css 或者 App.vue 中 */ .el-table th, .el-table td { padding: 8px; } ``` #### 利用 scoped 样式作用域 如果希望仅影响某个具体页面上的组件而不干扰其他部分,则可以在单文件组件(SFC)内部使用 `<style scoped>` 来限定CSS的作用范围[^4]。 ```html <template> <!-- ... --> </template> <script setup lang="ts"> // ... </script> <style scoped> @import &#39;element-plus/theme-chalk/el-table.css&#39;; .custom-class .el-table__row { background-color: #f0f9eb !important; /* 强制设置背景颜色 */ } .custom-class >>> .cell { /* 深度选择器用于穿透scoped限制 */ color: red; } </style> ``` > **注意**: 当前版本的 Vue 和某些构建工具可能不再支持 `/deep/`, `>>>` 或 ::v-deep 等深度选择器语法,请根据实际情况选用适的替代方案如 :global() 或 @at-root[]. #### 创建主题变量并重写 Element Plus 支持基于 LESS/SASS 的主题定制功能,允许开发者轻松更改整个应用的颜色、间距等基础属性。可以通过修改这些预设的主题变量来自定义组件风格[^2]. ```scss $--color-primary: #ff6700; @import "~element-plus/packages/theme-chalk/src/index"; ``` #### 动态绑定类名与内联样式 除了静态方式外,还可以利用Vue的数据绑定特性动态改变元素的class名称或是inline-style, 实现更加灵活多变的效果[^3]. ```vue <template> <div class="table-container" :class="{ active: isActive }"> <el-table :data="listData" style="width: 100%" /> </div> </template> <script setup lang="ts"> const isActive = ref(true); let listData = reactive([ {"date": "2016-05-02", "name": "Tom"}, ]); </script> <style scoped> .table-container.active .el-table tr:hover{ cursor:pointer; background:#eafaff!important; } </style> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值