vue3 hooks element table 动态多列合并单元格

19 篇文章 0 订阅
2 篇文章 0 订阅

vue3 hooks element table 动态多列合并相邻相同prop值单元格

// 合并多列表格--业务hooks

import { ref } from "@vue/composition-api";
import { DESIGN_QUANTITY, EBS_NAME, EBS_CODE } from "../data";
export default function useTableMultipleColumns() {
  const mergeObj = ref({}); //  保存处理完合并的信息
  const PROP_COUNT = "PropCount"; // 常量-表示当前prop和上一个prop 相等的次数
  const CURRENT_INDEX = "CurrentIndex"; // 常量 -保存当前的index

  const getJoinPropStr = ({ v, item, data, index }) => { 
     // 这个函数不用关注,这是业务内容处理,
     // 
    //  业务内容--根据prop ,得到拼接后的 当前值和上一次的值
    let currentStr; // 当前prop 拼接后内容
    let prevStr;  // 当一个prop 拼接后的内容
    if (v === DESIGN_QUANTITY) {
      currentStr = `${item[v]} ${
        item["designQuantityCount"]
          ? "(共" + item["designQuantityCount"] + "条记录)"
          : ""
      }`;

      prevStr = `${data[index - 1][DESIGN_QUANTITY]} ${
        data[index - 1]["designQuantityCount"]
          ? "(共" + data[index - 1]["designQuantityCount"] + "条记录)"
          : ""
      }`;
    } else if (v === "name") {
      currentStr = `${item[EBS_NAME]} ${
        item[EBS_CODE] ? "(" + item[EBS_CODE] + ")" : ""
      }`;

      prevStr = `${data[index - 1][EBS_NAME]} ${
        data[index - 1][EBS_CODE] ? "(" + data[index - 1][EBS_CODE] + ")" : ""
      }`;
    }

    return {
      currentStr,
      prevStr,
    };
  };

  const getMergeArr = (data, prop=[]) => {
    // 获取合并信息--获取想要合并单元格的prop出现的次数,用来后续合并单元格
    if (!prop||!Array.isArray(prop)) return;
    data.forEach((item, index) => {
      prop.forEach((v, i) => {
        if (index === 0) {
          mergeObj.value[v + PROP_COUNT] = [];
          mergeObj.value[v + PROP_COUNT].push(1);
          mergeObj.value[v + CURRENT_INDEX] = 0;
        } else {
          const { currentStr, prevStr } = getJoinPropStr({//  这里如果你们只是单纯要比较 prop的值的话,直接用 当前prop的值和上一个porp的值去做比较就好了,不用写这步
            v,
            item,
            data,
            index,
          });
          if (currentStr === prevStr) {
            mergeObj.value[v + PROP_COUNT][
              mergeObj.value[v + CURRENT_INDEX]
            ] += 1;
            mergeObj.value[v + PROP_COUNT].push(0);
          } else {
            mergeObj.value[v + PROP_COUNT].push(1);
            mergeObj.value[v + CURRENT_INDEX] = index;
          }
        }
      });
    });
  };

  const resetMergeObj = () => { // 重置resetMergeObj防止以前的数据造成合并单元格错误
    resetMergeObj.value = {};
  };

  const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
    if (columnIndex === 2) {// 要合并的第几列
      const _row = mergeObj.value[DESIGN_QUANTITY + PROP_COUNT][rowIndex]; // DESIGN_QUANTITY 这是要合并的prop
      const _col = _row > 0 ? 1 : 0;
      return {
        rowspan: _row,
        colspan: _col,
      };
    } else if (columnIndex === 1) {
      const _row = mergeObj.value["name" + PROP_COUNT][rowIndex];
      const _col = _row > 0 ? 1 : 0;
      return {
        rowspan: _row,
        colspan: _col,
      };
    }
  };

  return {
    mergeObj,

    getMergeArr,
    resetMergeObj,
    objectSpanMethod,
  };
}

没有单独去写 公共处理的函数的,这个例子里面包含了我一部分业务处理内容,下面贴上效果图
比如我要合并第一和第二列 prop相同的值。
在这里插入图片描述
调用函数:

  const query = (row) => { // 请求表格列表
    loading.value = true;
    const { workSiteId, statisticsCode } = row;
    const params = {
      workSiteId,
      statisticsCode,
    };
    treeModelQuantity(params)
      .then((res) => {
        resetMergeObj();  // 重置数据
        tableDate.value = res?.data;
        res?.data && getMergeArr(res?.data, [DESIGN_QUANTITY, "name"]);  // 将列表数据,和要合并的 单元格的 prop 传入
      })
      .finally(() => {
        loading.value = false;
      });
  };

// 最后调用 在table标签 传入合并函数
 :summary-method="summaryMethod"

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现动态合并列,可以使用 Element Plus 表格组件提供的 `span-method` 属性。该属性可以设置一个方法,用于动态计算每个单元格需要合并的行数和列数。 下面是一个示例代码,使用 TypeScript 和 Element Plus 表格组件实现动态合并列: ```typescript <template> <el-table :data="tableData" :span-method="mergeCell" > <el-table-column prop="name" label="名称" /> <el-table-column prop="age" label="年龄" /> <el-table-column prop="gender" label="性别" /> <el-table-column prop="score" label="分数" /> </el-table> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ElTableColumn, ElTableRow } from 'element-plus'; export default defineComponent({ data() { return { tableData: [ { name: '张三', age: 18, gender: '男', score: 90, }, { name: '李四', age: 20, gender: '女', score: 85, }, { name: '王五', age: 22, gender: '男', score: 95, }, ], }; }, methods: { mergeCell({ row, column, rowIndex, columnIndex }: { row: Record<string, any>; column: ElTableColumn; rowIndex: number; columnIndex: number; }): { rowspan: number; colspan: number; } { // 判断第一列是否相同 if (columnIndex === 0) { let rowspan = 1; for (let i = rowIndex + 1; i < this.tableData.length; i++) { if (this.tableData[i].name === row.name) { rowspan++; } else { break; } } return { rowspan, colspan: 1, }; } // 其他列不需要合并 return { rowspan: 0, colspan: 0, }; }, }, }); </script> ``` 在上面的代码,`mergeCell` 方法会接收一个参数,包含当前单元格的行数据、列数据、行索引和列索引。通过判断第一列的值是否相同,动态计算需要合并的行数和列数,然后返回一个对象。 需要注意的是,`span-method` 属性的值是一个函数,需要使用 `defineComponent` 方法定义组件,并将该函数作为组件的一个方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值