vue el-table表格如何实现合并单元格 + 合计 + 自定义表格高度 + 页面Loadding

关于该功能element官网有详细的教程,但是很多经验和坑还需要自己去踩,故此记录一下,废话不多说,直接上代码!

1. 项目需求图展示:

2. DOM代码

javascript 复制代码
<lls-table v-loading="layerLoading" :height="tableHeight" :summary-method="getSummaries" show-summary :span-method="mergeCells" :data="tableList">
  <lls-table-column prop="groupName" min-width="150" align="center" label="集团名称"></lls-table-column>
  <lls-table-column prop="coreEnterpriseName" min-width="130" align="center" label="核心企业"></lls-table-column>
  <lls-table-column min-width="180" align="center" label="供应商">
      <lls-table-column label="名称" min-width="90" align="center" prop="supplierName"> </lls-table-column>
      <lls-table-column label="数量" min-width="90" align="center" prop="supplierNumber"></lls-table-column>
      <lls-table-column label="日新增" min-width="90" align="center" prop="supplierAddNumber"></lls-table-column>
  </lls-table-column>
 </lls-table>
 
 // 备注:
     1. `show-summary`设置为`true`就会在表格尾部展示合计行
     2. `summary-method`传入一个方法,返回一个数组,这个数组中的各项就会显示在合计行的各列中,
     3. `span-method`方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行`row`、当前列`column`、当前行号`rowIndex`、当前列号`columnIndex`四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表`rowspan`,第二个元素代表`colspan`。 也可以返回一个键名为`rowspan`和`colspan`的对象。

3.js代码

ini 复制代码
export default {
  data() {
    return {
      tableHeight: "400px",
      supplierLedgerList: [], //表格数据对象
      summation: {}, //表格数据汇总
      layerLoading: false, //全局loading
    };
  }
},
computed: {
    tableList() {
      // reduce方法将接口返回的回调Promise进行处理  res为接口返回的Promise数组
      return this.supplierLedgerList.reduce((res, item) => {
        // item为Promise数组map后的每一项item
        const list = item.records.map((subItem, subIndex) => {
          return {
            ...subItem, 
            groupName: item.groupName
          }
        })
        // 将接口返回的Promise对象和当前的数据和list数组进行合并,后面用来填充表格,也就是说,不管表格有多少合并项,结构多复杂,处理后的最终数据结构,对应上表格的DOM结构即可
        return [...res, ...list]
      },[])
    },
    mergeObj() {
      let groupNameArr = [], groupIndex = 0, coreCompanyArr = [], coreCompanyIndex = 0;
      // tableList为reduce方法处理合并后的数据
      this.tableList.forEach((item, index) => {
        if (index === 0) {
          groupNameArr.push(1);
          groupIndex = 0;
          coreCompanyArr.push(1);
          coreCompanyIndex = 0;
        } else {
          if (item.groupName === this.tableList[index - 1].groupName) {
            groupNameArr[groupIndex] += 1;
            groupNameArr.push(0);
          } else {
            groupNameArr.push(1);
            groupIndex = index;
          }
          if (item.groupName === this.tableList[index - 1].groupName && item.coreEnterpriseName === this.tableList[index - 1].coreEnterpriseName) {
            coreCompanyArr[coreCompanyIndex] += 1;
            coreCompanyArr.push(0);
          } else {
            coreCompanyArr.push(1);
            coreCompanyIndex = index;
          }
        }
      })
      return { groupNameArr, coreCompanyArr }
    }
 }
 mounted() {
   this.$nextTick(() => {
     // 获取浏览器视图高度
     let screenHeight = document.body.offsetHeight;
     // let searchBarHeight = this.$refs.searchBar.clientHeight,如果表格上分还有搜索条件DOM,就用此方法
     // 减去对于的
     let dataContent = screenHeight - 142
     this.tableHeight = `${dataContent}px`;
   });
 },
methods: {
    getData() {
      this.layerLoading = true;
      // listPage表格接口  count底部合计接口
      Promise.all([this.$http.post('/listPage'), this.$http.post('/count')]).then(res => {
        this.layerLoading = false;
        if (res.every(item => item.code === '200')) {
          this.supplierLedgerList = res[0].data || [];
          this.summation = res[1].data || {};
        } else {
          this.$llsAlert({
            type: "error",
            text: res.message,
          });
        }
      })
    },
   // 自定义合计列内容
   getSummaries(param) {
      const { columns } = param;
      const sums = [];
      // 自定义需要合并的列(场景:该合并后的数据由count接口返回,需将返回数据插在对应的列中)
      const propertyMap = {
        // 对应表格需要展示合并的列
        coreEnterpriseName: 'coreNumber',
        supplierName: 'supplierNumber',
        supplierNumber: 'supplierTotalNumber',
        supplierAddNumber: 'supplierAddNumber'
      }
      columns.forEach((column, index) => {
        // 自定义第一列合并文本
        if (index === 0) {
          sums[index] = '总计';
          return;
        } else {
          // 将count接口返回的合计数据插入到表格中(表格下方的合计为接口返回)
          const property = column.property
          sums[index] = this.summation[propertyMap[property]];
        }
      });
      return sums;
    },
    
    // 自定义合并列
    mergeCells({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        // 第一列的合并方法
        const rowspan = this.mergeObj.groupNameArr[rowIndex];
        const colspan = rowspan > 0 ? 1 : 0;
        return {
          rowspan,
          colspan
        };
      } else if (columnIndex === 1) {
        // 第二列的合并方法
        const rowspan = this.mergeObj.coreCompanyArr[rowIndex];
        const colspan = rowspan > 0 ? 1 : 0; 
        return {
          rowspan,
          colspan
        };
      }
    },
}

接口返回数据结构

  • 表格底部合计数据
  • 表格数据
  • reduce()方法合并后的表格数据
  • getSummaries()方法返回的数据结构
  • columns展开后的数据结构
  • data展开后的数据结构

END...

相关推荐
陈随易2 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
Dream-Y.ocean4 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Csvn5 小时前
性能监控
前端
Highcharts.js5 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
Csvn5 小时前
构建工具
前端
FRing036 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷6 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen8 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒8 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫9 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库