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...

相关推荐
你挚爱的强哥7 分钟前
【sgCreateCallAPIFunctionParam】自定义小工具:敏捷开发→调用接口方法参数生成工具
前端·javascript·vue.js
喝旺仔la12 分钟前
Element 表格相关操作
javascript·vue.js·elementui
繁依Fanyi15 分钟前
使用 Spring Boot + Redis + Vue 实现动态路由加载页面
开发语言·vue.js·pytorch·spring boot·redis·python·算法
米老鼠的摩托车日记15 分钟前
【vue element-ui】关于删除按钮的提示框,可一键复制
前端·javascript·vue.js
forwardMyLife15 分钟前
element-plus的菜单组件el-menu
javascript·vue.js·elementui
猿饵块1 小时前
cmake--get_filename_component
java·前端·c++
好多吃的啊1 小时前
背景图鼠标放上去切换图片过渡效果
开发语言·javascript·ecmascript
大表哥61 小时前
在react中 使用redux
前端·react.js·前端框架
Passion不晚1 小时前
打造民国风格炫酷个人网页:用HTML和CSS3传递民国风韵
javascript·html·css3
十月ooOO1 小时前
【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标
前端·chrome·计算机外设