el-table组件只有合并列后加排序的,没有合并行后加排序

需求是:相同属性值合并的行是一大类,后面的列升序或降序是指在这每一大类中排序。

思路是:通过接口获取到的一维数组,根据对象数组中对象的某个属性值进行拆分成一个二维数组,二维数组内部进行排序,再解构成一维数组,重新计算需要合并行数。

因为是合并行之后加的排序,所以el-table-column的sortable属性值不能简单的为true需要为’custom',el-table需要添加sort-change方法

html部分

 <el-table ref="table1" :data="tableData" :span-method="objectSpanMethod" @sort-change="sortChange" stripe border class="w-100" height="92%">
   <el-table-column v-for="item in tableHeads" :key="item.label" :label="item.label"     
     :sortable="(['area', 'yearMonth'].includes(item.prop) || item.children && 
      item.children.length) ? false : 'custom'" :prop="item.prop">
      <el-table-column v-for="j in item.children" :key="j.prop" :prop="j.prop" :label="j.title ? j.title : j.label" sortable="custom"></el-table-column>
    </el-table-column>
 </el-table>

js部分 

// 排序逻辑,sortable属性值一定要是'custom'
sortChange ({ column, prop, order }) {
   // order 有三种情况 null,'descending','ascending'
   if (!order) {
       // 等于原来接口获取到的值 _cloneDeep就是loadsh插件里面的深拷贝方法
      this.tableData = _cloneDeep(this.originTableData) 
   } else {
       // 拆分成数组,排序后合并
       const newArr = this.tableData.reduce((acc, obj) => {
           const area = obj.area
           const areaArray = acc.find(arr => arr[0]?.area === area)
           if (areaArray) {
              areaArray.push(obj)
           } else {
              acc.push([obj])
           }
           return acc
       }, [])
       newArr.forEach(subArr => {
          // 原先合并行的字段,目前只能清除重新计算
          subArr.forEach(item => {
            item.allNum = ''
          })
          if (order === 'descending') {
            subArr.sort((a, b) => {
              return (b[prop] !== '-') - (a[prop] !== '-') || b[prop] - a[prop]
            })
          } else {
            subArr.sort((a, b) => {
              return (a[prop] !== '-') - (b[prop] !== '-') || a[prop] - b[prop]
            })
          }
         // 若是还有一个合并行的,可以再写一个sort()方法,把具有相同属性的再排序在一起,既满足排序,又满足合并行
      })
      // 利用数组自带的flat()方法将多维数组变为一维数组
      // againHandleData是合并行数的方法
      this.tableData = this.againHandleData(newArr.flat(1), 'area', 'allNum')
   }
},

//计算合并行数办法
/**
 * 一个表格多列合并表格数据
 * @param {Array} data 未合并的表格数据
 * @param {String} key 合并单元的列字段
 * @param {String} allNum 合并单元描述字段
 * @returns 合并表格数据
 */
againHandleData (data, key, allNum) {
  const array = _cloneDeep(data || [])
  if (array.length >= 1) {
    let allNumIndex = 0
    let samePrv = array[0][key]
    for (let index = 1; index < array.length; index++) {
      const element = array[index]
      if (element[key] !== samePrv) {
        array[allNumIndex][allNum] = index - allNumIndex
        allNumIndex = index
        samePrv = element[key]
      }
    }
    array[allNumIndex][allNum] = array.length - allNumIndex
  }
  return array
}

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐