Element Plus Table 组件扩展:表尾合计功能详解

前言

在现代数据驱动的社会中,数据分析和统计成为了非常重要的任务。为了更有效地分析数据和展示统计结果,前端开发人员可以使用Vue框架和Element Plus组件库来实现数据的统计和分析功能。以下是一个关于如何在 Element Plus 的 el-table 组件中实现行汇总功能的文档,这个示例将展示如何计算每行的特定列的总和并显示在一个额外的汇总行中。

一、准备工作

安装 Element Plus

首先,确保已经安装了 Element Plus。如果还没有安装,可以使用 npm 或 yarn 进行安装:

bash 复制代码
npm install element-plus --save
# 或者使用 yarn yarn add element-plus

引入和注册 Element Plus

在 Vue 项目中,首先需要引入并注册 Element Plus 的组件:

javascript 复制代码
// main.js 或 main.ts
import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
const app = createApp(App);
app.use(ElementPlus);
app.mount('#app');

表尾合计功能实现

数据准备

在进行数据的统计和分析之前,需要准备好相应的数据。可以从后端API获取数据,也可以使用假数据。为了方便起见,我们在本文中使用假数据。

javascript 复制代码
[
    {"id":"12987122","name":"王小虎","amount1":"234","amount2":"3.2","amount3":10},
    {"id":"12987123","name":"王小虎","amount1":"165","amount2":"4.43","amount3":12},
    {"id":"12987124","name":"王小虎","amount1":"324","amount2":"1.9","amount3":9},
    {"id":"12987125","name":"王小虎","amount1":"621","amount2":"2.2","amount3":17},
    {"id":"12987126","name":"王小虎","amount1":"539","amount2":"4.1","amount3":15}
]

基础的表尾合计功能

在使用Element Plus时,表格合计是一个常见的需求,通常用于在表格底部显示某列或某几列数据的总和。在Element Plus中,可以通过配置表格的列定义来实现合计行,它可以帮助我们快速对表格中的数据进行汇总和展示。在 Vue 中实现表格的表尾合计功能相当简单,el-table通过添加 show-summary 属性即可在表格底部显示合计行,实现基础表尾合计功能。这个功能默认是关闭的,需要显式开启。默认情况下,对于合计行,第一列不进行数据求合操作,而是显示「合计」二字(可通过 sum-text 配置),其余列会将本列所有数值进行求合操作,并显示出来。

html 复制代码
<script setup lang="ts">
import { ElementPlus } from '@element-plus/icons-vue'
import { version as epVersion } from 'element-plus'
import { ref, version as vueVersion } from 'vue'

const tableDataWithSummary = ref([
  {id: '12987122',name: '王小虎',amount1: '234',amount2: '3.2',amount3: 10},
  {id: '12987123',name: '王小虎',amount1: '165',amount2: '4.43',amount3: 12},
  {id: '12987124',name: '王小虎',amount1: '324',amount2: '1.9',amount3: 9},
  {id: '12987125',name: '王小虎',amount1: '621',amount2: '2.2',amount3: 17},
  {id: '12987126',name: '王小虎',amount1: '539',amount2: '4.1',amount3: 15}
]);

</script>

<template>
  <p>
    <el-icon color="var(--el-color-primary)"><ElementPlus /></el-icon>
    Element Plus {{ epVersion }} + Vue {{ vueVersion }}
  </p>
  <el-divider />

  <div>
    <el-table :data="tableDataWithSummary" border style="width: 100%" show-summary>
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1" sortable label="数值 1" />
      <el-table-column prop="amount2" sortable label="数值 2" />
      <el-table-column prop="amount3" sortable label="数值 3" />
    </el-table>
  </div>

  <div>
    <el-table :data="tableDataWithSummary" border style="width: 100%" show-summary sum-text="总价">
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1" sortable label="数值 1" />
      <el-table-column prop="amount2" sortable label="数值 2" />
      <el-table-column prop="amount3" sortable label="数值 3" />
    </el-table>
  </div>
</template>

进阶的表尾合计功能

我们已经成功实现了基础的表尾合计功能,但业务需求可能更为复杂,例如,我们希望在合计金额上再加上特定的货币符号和百分比等。这时,我们可以利用summary-method这个属性来定义自己的合计计算方法。这个属性接受一个函数作为参数,其中包含了列信息和数据信息,然后该函数将用于计算并返回一个合计结果数组。

html 复制代码
<script setup lang="ts">
import { ElementPlus } from '@element-plus/icons-vue'
import { version as epVersion } from 'element-plus'
import { ref, version as vueVersion } from 'vue'
import {VNode} from "vue";

// 需要进行统计的列
const summaryColumns = ref(["amount1"])

const tableDataWithSummary = ref([
  {id: '12987122',name: '王小虎',amount1: '234',amount2: '3.2',amount3: 10},
  {id: '12987123',name: '王小虎',amount1: '165',amount2: '4.43',amount3: 12},
  {id: '12987124',name: '王小虎',amount1: '324',amount2: '1.9',amount3: 9},
  {id: '12987125',name: '王小虎',amount1: '621',amount2: '2.2',amount3: 17},
  {id: '12987126',name: '王小虎',amount1: '539',amount2: '4.1',amount3: 15}
]);

// 尾部计算合计
const getSummaries = (param: {
  columns: any[]; // 所有列的集合
  data: any[]; // 原始数据
}) => {
  const {columns, data} = param;
  const sums: ( number | string | VNode)[] = [];
  columns.forEach((column, index) => {
    // 第一列不进行求和操作,例如日期列或不需要的列,通用显示文字'合计'或其他标识符,根据需要自定义。
    if (index === 0) {
      sums[index] = '合计';
      return;
    }

    // 最后一列通常是操作列,不进行求和操作,可以留空或者根据需要显示文字。
    // if (index === columns.length - 1) {
      // sums[index] = '';
      // return;
    // }

    // 判断遍历的数据类型是否能转换成数值类型,如果可以就表明值是 number类型,否则是string类型。判断string类型是否是空字符串,为空字符换成0,不为空字符串就不做处理。
    const values = data.map(
      (item) => !isNaN(Number(item[column.property])) ? !isNaN(parseFloat(item[column.property])) ? parseFloat(item[column.property]) : item[column.property] == '' ? 0 : item[column.property] : item[column.property]
    );
    // 一个空的结果数组,用来存放每一列的和
    let sum: any = null;
    //判断数组中是否包含有string类型的值,并且是否能转换成number类型(空字符串换成number类型为0)。如果不行,那就是说明包含了字符串类型的值。
    if (values.every(item => !isNaN(Number(item)))) {
      // 这是个遍历数组的方法(用作累加器),第一个参数为回调函数,第二个参数为累加初始值。
      sum = values.reduce((total, currentValue) => {
        const value = Number(total);
        // 确定数据是否为空,不为空进行计算,为空返回原值
        if (!isNaN(value)) {
          return total + currentValue;
        } else {
          return total;
        }
      }, 0);
    } else {
      // 判断是否为空,如果不为空就赋值sum
      values.map(item => {
        if (item != '') {
          sum = 0
        }
      })
    }
    if (summaryColumns.value.includes(column.property)) {
      sums[column.property] = sum;
    }
  });

  // 根据实际列顺序返回 sums 数组
  return columns.map((_, index) =>
    index === 0 ? sums[0] : sums[columns[index].property] || ""
  )
}
</script>

<template>
  <p>
    <el-icon color="var(--el-color-primary)"><ElementPlus /></el-icon>
    Element Plus {{ epVersion }} + Vue {{ vueVersion }}
  </p>
  <el-divider />

  <div>
    <el-table :data="tableDataWithSummary" border style="width: 100%" show-summary :summary-method="getSummaries">
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1" sortable label="数值 1" />
      <el-table-column prop="amount2" sortable label="数值 2" />
      <el-table-column prop="amount3" sortable label="数值 3" />
    </el-table>
  </div>
</template>

上段代码的功能是对表格中的数据进行合计处理。首先,通过解构赋值从参数中获取到columns和data,其中columns代表每列数据的属性,通常在HTML中使用prop属性进行绑定。然后,利用forEach方法遍历每一列,对于每一列的数据,我们使用reduce()方法进行合计,并将结果存储在sums数组中对应的位置。这样,最终我们得到了一个包含各列合计结果的数组。

需要注意的是,在实际的业务场景中,表格的数据可能涉及多页,单页计算可能并不足够,后端通常需要生成专门的合计字段来进行处理,通过接口返回给前端,前端展示表尾合计行。

html 复制代码
<script setup lang="ts">
import {ElementPlus} from '@element-plus/icons-vue'
import {version as epVersion} from 'element-plus'
import {ref, version as vueVersion} from 'vue'
import {TableColumnCtx} from "element-plus";
import {VNode} from "vue";

const tableDataWithSummary = ref({
  tableData: [
    {id: '12987122', name: '王小虎', amount1: '234', amount2: '3.2', amount3: 10},
    {id: '12987123', name: '王小虎', amount1: '165', amount2: '4.43', amount3: 12},
    {id: '12987124', name: '王小虎', amount1: '324', amount2: '1.9', amount3: 9},
    {id: '12987125', name: '王小虎', amount1: '621', amount2: '2.2', amount3: 17},
    {id: '12987126', name: '王小虎', amount1: '539', amount2: '4.1', amount3: 15}
  ], tableSum: {
    amount1Sum: 1883,
    amount2Sum: 15.83,
    amount3Sum: 63
  }
});

interface UserInfo {
  id: string;
  name: string;
  amount1: string;
  amount2: string;
  amount3: number;
}

interface SummaryMethodProps<T = UserInfo> {
  columns: TableColumnCtx<T>[] // 所有列的集合
  data: T[] // 原始数据
}

// 尾部计算合计
const getSummaries = (param: SummaryMethodProps) => {
  const sums: (string | number | VNode)[] = [];
  param.columns.forEach((column, index) => {
    // 第一列不进行求和操作,例如日期列或不需要的列,通用显示文字'合计'或其他标识符,根据需要自定义。
    if (index === 0) {
      sums[index] = '合计';
      return;
    }
    // 根据当前列绑定的字段名进行判断,根据字段名决定展示什么内容
    switch (column.property) {
      case 'amount1':
        sums[index] = tableDataWithSummary.value.tableSum.amount1Sum;
        break;
      case 'amount2':
        sums[index] = tableDataWithSummary.value.tableSum.amount2Sum;
        break;
      case 'amount3':
        sums[index] = tableDataWithSummary.value.tableSum.amount3Sum;
        break;
      default:
        sums[index] = '';
        break;
    }
  });
  // 根据实际列顺序返回 sums 数组
  return param.columns.map((_, index) =>
    index === 0 ? sums[0] : sums[index] || ''
  )
}
</script>

<template>
  <p>
    <el-icon color="var(--el-color-primary)">
      <ElementPlus />
    </el-icon>
    Element Plus {{ epVersion }} + Vue {{ vueVersion }}
  </p>
  <el-divider />

  <div>
    <el-table :data="tableDataWithSummary.tableData" style="width: 100%" show-summary :summary-method="getSummaries">
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="amount1" sortable label="数值 1" />
      <el-table-column prop="amount2" sortable label="数值 2" />
      <el-table-column prop="amount3" sortable label="数值 3" />
    </el-table>
  </div>
</template>

小结

使用Vue和Element Plus可以方便地实现数据的统计功能。在本文中,我们介绍了如何展示数据、统计数据,并提供了相关的代码示例。在实际项目中,可以根据具体需求进一步扩展和优化该组件。

相关推荐
德育处主任17 分钟前
p5.js 圆弧的用法
前端·javascript·canvas
Arvin6272 小时前
Nginx IP授权页面实现步骤
服务器·前端·nginx
xw53 小时前
Trae安装指定版本的插件
前端·trae
默默地离开3 小时前
前端开发中的 Mock 实践与接口联调技巧
前端·后端·设计模式
南岸月明3 小时前
做副业,稳住心态,不靠鸡汤!我的实操经验之路
前端
嘗_3 小时前
暑期前端训练day7——有关vue-diff算法的思考
前端·vue.js·算法
MediaTea4 小时前
Python 库手册:html.parser HTML 解析模块
开发语言·前端·python·html
杨荧4 小时前
基于爬虫技术的电影数据可视化系统 Python+Django+Vue.js
开发语言·前端·vue.js·后端·爬虫·python·信息可视化
BD_Marathon4 小时前
IDEA中创建Maven Web项目
前端·maven·intellij-idea
waillyer4 小时前
taro跳转路由取值
前端·javascript·taro