• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

element plus el-table 部分属性值相同的行合并

武飞扬头像
徐文豪
帮助3

背景

接了个外快需要在表格实现以下效果:

学新通

查文档

element文档中有“合并行或列”的例子: 多行或多列共用一个数据时,可以合并行或列。

通过给 table 传入span-method方法可以实现合并行或列, 方法的参数是一个对象,里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组,第一个元素代表 rowspan,第二个元素代表 colspan。 也可以返回一个键名为 rowspan 和 colspan 的对象。

学新通

<template>
  <div>
    <el-table
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px"
    >
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="name" label="Name" />
      <el-table-column prop="amount1" label="Amount 1" />
      <el-table-column prop="amount2" label="Amount 2" />
      <el-table-column prop="amount3" label="Amount 3" />
    </el-table>
  </div>
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus'

interface User {
  id: string
  name: string
  amount1: string
  amount2: string
  amount3: number
}

interface SpanMethodProps {
  row: User
  column: TableColumnCtx<User>
  rowIndex: number
  columnIndex: number
}

const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  if (columnIndex === 0) {
    if (rowIndex % 2 === 0) {
      return {
        rowspan: 2,
        colspan: 1,
      }
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
  }
}

const tableData: User[] = [
  {
    id: '12987122',
    name: 'Tom',
    amount1: '234',
    amount2: '3.2',
    amount3: 10,
  },
  {
    id: '12987123',
    name: 'Tom',
    amount1: '165',
    amount2: '4.43',
    amount3: 12,
  },
  {
    id: '12987124',
    name: 'Tom',
    amount1: '324',
    amount2: '1.9',
    amount3: 9,
  },
  {
    id: '12987125',
    name: 'Tom',
    amount1: '621',
    amount2: '2.2',
    amount3: 17,
  },
  {
    id: '12987126',
    name: 'Tom',
    amount1: '539',
    amount2: '4.1',
    amount3: 15,
  },
]
</script>

结合例子与具体需求分析

官方给的例子核心代码其实是这个:

const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  if (columnIndex === 0) {
    if (rowIndex % 2 === 0) {
      return {
        rowspan: 2, 
        colspan: 1,
      }
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
  }
}

上面代码的意思就是: 当行数为偶数行(rowIndex % 2 === 0)时,合并第一列(columnIndex === 0)的当前行(rowIndex)和下一奇数行(rowspan: 2)

  1. rowspan用来指定单元格纵向跨越的行数:rowspan=2就是合并两行。 
  2. colspan用来指定单元格横向跨越的列数:colspan=2就是合并两列。

这个列子和我的需求差距有点大。。。。。我的项目需求是:当设备,检测人等属性相同时,合并相同的行对应属性的列。

代码

多说无益直接上研究出来的代码(删除了部分属性,简化代码)

<script setup name="Reportdetail" lang="ts">
import type { TableColumnCtx } from 'element-plus'
import { ReportFormsService } from '@/api/analysis'

interface ReportDetail {
  deviceName: string
  userName: string
  value1: string
  value2: string
  value3: string
  value4: string
  value5: string
  detectionTime: string
  groups: string
}

//需要判断的属性组
const spanProps = [
  'deviceName',
  'userName',
  'detectionTime',
  'groups',
]

interface SpanMethodProps {
  row: ReportDetail
  column: TableColumnCtx<ReportDetail>
  rowIndex: number
  columnIndex: number
}

let rowSpansMap = new Map() //存需要开始合并的行号,向下合并多少行

/**
 * 根据列表数据得出需要合并的行
 * @param data 列表数据
 */
const spanPropGroup = (data: any) => {
  let oldRow = null //需要合并的行
  rowSpansMap = new Map() //重置Map

  oldRow = data[0] //默认第0行为需要合并的行
  rowSpansMap.set(0, 1) //第0行,向下合并一行(其实就是自己单独一行)
  let spanRow = 0 //记录需要开始合并的行号
  for (let i = 1; i < data.length; i  ) {
    const item = data[i]
    let isSame = true
    //遍历需要判断的属性判断对应值是否全部相等
    for (let j = 0; j < spanProps.length; j  ) {
      const prop = spanProps[j]
      //只要有一个属性值不相等则记录新的需要合并的行号
      if (item[prop] != oldRow[prop]) {
        oldRow = item
        rowSpansMap.set(i, 1)
        spanRow = i
        isSame = false
        break
      }
    }
    //如果所有属性值相同则所需要合并的行数 1
    if (isSame) {
      let span = rowSpansMap.get(spanRow)
      rowSpansMap.set(spanRow, span   1)
    }
  }
}

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
  //采样值1-5列所对应的行不需要合并
  if (
    columnIndex != 8 &&
    columnIndex != 9 &&
    columnIndex != 10 &&
    columnIndex != 11 &&
    columnIndex != 12
  ) {
    //根据当前行号从map中获取开始合并的行号,向下合并多少行
    const span = rowSpansMap.get(rowIndex)
    if (span != null) {
      return {
        rowspan: span,//向下合并span行
        colspan: 1,
      }
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
  }
}

const route = useRoute()
const listLoading = ref(false)
const list = ref([])
//请求数据接口类(需继承ListAPI)
const listApi = new ReportFormsService()

const search = async (collectId: any) => {
  list.value = []
  listLoading.value = true
  try {
    const res = await listApi.listDetail(collectId)
    const { code, data } = res
    if (code == 200 && data) {
      //根据列表数据得出需要合并的行
      spanPropGroup(data)
      list.value = data
    }
  } catch (error) {
    console.log('🚀 ~ file: index.vue:73 ~ search ~ error:', error)
  }
  listLoading.value = false
}
search(route.params && route.params.collectId)
</script>

html代码

<template>
  <el-container class="app-container">
    <el-main>
      <el-table v-loading="listLoading" :data="list" :span-method="objectSpanMethod">
        <el-table-column label="设备" align="center" prop="deviceName" show-overflow-tooltip />
        <el-table-column label="检测人" align="center" prop="userName" show-overflow-tooltip />

        <el-table-column
          label="工作面厚度差值"
          align="center"
          prop="workFaceThicknessDiff"
          show-overflow-tooltip
        />
        <el-table-column
          label="锟端-工作面"
          align="center"
          prop="workFaceRollerEnd"
          show-overflow-tooltip
        />
        <el-table-column label="整体均值" align="center" prop="overallMean" show-overflow-tooltip />
        <el-table-column
          label="工作面中值"
          align="center"
          prop="workFaceMidValue"
          show-overflow-tooltip
        />
        <el-table-column
          label="工作面最大值"
          align="center"
          prop="workFaceMaxValue"
          show-overflow-tooltip
        />
        <el-table-column
          label="工作面最小值"
          align="center"
          prop="workFaceMinValue"
          show-overflow-tooltip
        />
        <el-table-column label="取样点1(mm)" align="center" prop="value1" show-overflow-tooltip />
        <el-table-column label="取样点2(mm)" align="center" prop="value2" show-overflow-tooltip />
        <el-table-column label="取样点3(mm)" align="center" prop="value3" show-overflow-tooltip />
        <el-table-column label="取样点4(mm)" align="center" prop="value4" show-overflow-tooltip />
        <el-table-column label="取样点5(mm)" align="center" prop="value5" show-overflow-tooltip />
        <el-table-column
          label="检测时间"
          align="center"
          prop="detectionTime"
          show-overflow-tooltip
        />
        <el-table-column label="班组" align="center" prop="groups" show-overflow-tooltip />
        <el-table-column label="班次" align="center" prop="classes" show-overflow-tooltip />
      </el-table>
    </el-main>
  </el-container>
</template>

最终效果

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhacfb
系列文章
更多 icon
同类精品
更多 icon
继续加载