Vue3结合Naive UI中 n-data-table表格动态合并单元格

 <n-data-table   :columns="columns" :data="tableData" :single-line="false" />

columns部分

const columns = ref<DataTableColumns>([
  {
    title: '序号',
    key: 'riskPointCode',
    align: 'center',
    width: 120,
    render(row, rowIndex) {
      return (pagination.page - 1) * pagination.pageSize + rowIndex + 1
    }
  },
  {
    title: '名字',
    key: 'name',
    align: 'center',
    width: 120,
    rowSpan: (rowData, rowIndex) => {
      let rowSpanDataObj = rowSpanData.value.name[rowIndex + 1]
      if (rowSpanDataObj) {
        return rowSpanDataObj.number
      }
    },
  },
])

// 定义一个函数,获取在第几行合并 合并多少个 

 rowSpanData.value = processList( 接口数据 || []);
function processList(list: any) {
  let result: any = {};
  for (let key in list[0]) {
    let currentValue = list[0][key];
    let count = 1;
    let index = 1;
    let tempResult: any = {};
    for (let i = 1; i < list.length; i++) {
      if (list[i][key] === currentValue) {
        count++;
      } else {
        if (count > 1) {
          tempResult[index] = { number: count };
        }
        currentValue = list[i][key];
        count = 1;
        index = i + 1;
      }
    }
    if (count > 1) {
      tempResult[index] = { number: count };
    }
    result[key] = tempResult;
  }
  return result;
}

返回结果

{
    "name": {
        "1": {
            "number": 2
        },
        "3": {
            "number": 8
        }
    },
    "name2": {
        "2": {
            "number": 5
        },
        "7": {
            "number": 4
        }
    }
   
}

补充一个方法但是效率没有第一个好

// 定义一个函数,用于获取相同名称的最后一行的索引  二选一用
const getLastIndex = (index: any, names: any, types: any) => {
  const sameNameIndex = tableData.value.slice(index).findIndex((item: any) => {
    return names.some((name: any, i: any) => item[types[i]] !== name);
  });
  return sameNameIndex === -1 ? tableData.value.length : sameNameIndex;
};

使用方法

 {
    title: '名字',
    key: 'name',
    align: 'center',
    width: 120,
    rowSpan: (rowData, rowIndex) => {
     return getLastIndex(rowIndex, [rowData.riskPointCode], ["riskPointCode"]);
    },
  },

除了最基础的相同内容合并还有按照需要的其他父级id相同合并

那么就可以采用

 getAllProcessList(_RES.rows || []) //获取合并数据 
const processList = (list: any[], nameList: string[]) => {
  const result: { index: number; bumber: number }[] = [];
  let currentIndex = 0;
  let currentCount = 1;
  let currentGroup: any = {};

  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    let isSameGroup = true;
    for (const key of nameList) {
      if (currentGroup[key] !== item[key]) {
        isSameGroup = false;
        break;
      }
    }

    if (!isSameGroup) {
      if (currentCount > 1) {
        result.push({ index: currentIndex, bumber: currentCount });
      } else {
        result.push({ index: currentIndex, bumber: 1 });
      }
      currentGroup = {};
      for (const key of nameList) {
        currentGroup[key] = item[key];
      }
      currentIndex = i;
      currentCount = 1;
    } else {
      currentCount++;
    }
  }
  result.push({ index: currentIndex, bumber: currentCount });
  result.splice(0, 1);
  return result;
};
const getAllProcessList = (list: any[]) => {
  rowSpanData.value = {
    pointId: processList(list, ['pointId']),
    id: processList(list, ['id']),
    dangerId: processList(list, ['id', 'dangerId']),
    inherentRisk: processList(list, ['id', 'dangerId', 'inherentRisk'])
// 想加什么依据合并都可以
   } 
  
}

执行结果

{
    "pointId": [
        {
            "index": 0,
            "bumber": 8
        },
        {
            "index": 8,
            "bumber": 2
        }
    ],
    "id": [
        {
            "index": 0,
            "bumber": 8
        },
        {
            "index": 8,
            "bumber": 2
        }
    ]
    ]
}

使用方法

 {
    title: '根据id和dangerId合并',
    key: 'pointId',
    align: 'center',
    width: 120,
    //  根据风险点id一样合并
    rowSpan: (rowData, rowIndex) => {
      let rowSpanDataObj: any = rowSpanData.value.dangerId.find((el: any) => { return 
       el.index == rowIndex })
      return rowSpanDataObj ? rowSpanDataObj.bumber : 1
    },
  },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值