表格的多列排序

1,528 阅读3分钟

工作中遇到了一个问题:有一个类似表格的dom结构,实际上完全可以当作表格,需要根据其中的两个列排序,包含逆序和顺序,记录一下当时的解决方案


因为原始的数据是数组类型的,所以使用数组的 sort() 方法比较方便,具体的使用方法详见MDN,因为是有可能是需要通过两个参数去排序,所以可以将这两个列的点击事件注册一下。使用的是vue框架,这里html部分就不写了,主要看JS逻辑

// 注册在列上的方法
/*
  orderType: 排序的类型 1:正序,-1:逆序,0:不排序
  col是当前点击的列项
  data: 表格的数据
  originData: 深拷贝一份表格数据
*/
sortTable(col) {
  if(col.orderType === undefined || col.orderType === 0) {
    // 深拷贝一份表格的数据
    this.originData = cloneDeep(this.data);
    this.$set(col,"orderType",1)
  }else if(col.orderType === 1) {
    this.$set(col, "orderType", -1)
  }else if(col.orderType === -1) {
    this.$set(col, "orderType", 0)
  }

  // 这里是将当前排序的列放到一个orderColList的数组中
  // 如果已经存在,那么删除掉原来位置的,重新添加到orderColList的第一项
  // 如果当前列需要排序(正序或者逆序),那么就放到第一个,这样后面排序的时候也是先根据这一列的顺序来的
  const ind = this.orderColList.find(c => {
    return c.prop === col.prop
  })
  if(ind !== -1) {
    this.orderColList.splice(ind,1)
  }
  if(col.orderType !== 0) {
    this.orderColList.unshift(col);
  }
  // 如果发现每一个排序列都是0,那么就是都不排序,就按照原来保存的顺序来
  const isOrigin = this.orderColList.every(c => {
    return c.orderType === 0 || c.orderType === undefined
  })
  if(isOrigin) {
    if(this.originData) {
      this.data = this.originData;
      return
    }
  }
  // 这个就是排序的方法
  this.sortData(this.data);
}

通过上面的代码,表格数据的排序,需要利用表格列项,需要用到一个数组(orderColList)存放排序的列,并且orderColList是有顺序的,毕竟多个列排序的时候会有一个主要,次要。

sortData方法

function sortData(arr) {
  // 使用原生JS的sort排序方法,orderFun就是我们排序的依照,sort接收的参数是一个function,那么this.orderFun()返回的必然也是一个function
  arr.sort(this.orderFun())
  // 如果表格存在树结构,那么其子项也需要排序,用到简单的递归
  arr.forEach(item => {
    if(item.children && item.children.length) {
      this.sortData(item.children)
    }
  })
}

/*
这里首先返回一个funtion,原因看上面
我们根据排序的逻辑,就是按照之前保存的orderColList这个方法来,越靠前的,我们越根据他的顺序,只有第0个的值相同,那么我们考虑下一个orderColList中的列,实现的根据后点击的列排序
如果发现这个列是不排序的,那么直接下一个就好
完全相同,return 0
*/
function orderFun () {
  const { orderColList } = this;
  return (a,b) => {
    for(let i=0; i<orderColList.length; i++) {
      if(orderColList[i].orderType === 0) {  // 如果发现这个列是不排序的,那么直接下一个就好
        break;
      }
      if(a[orderColList[i]["prop"]] > b[orderColList[i]["prop"]]) {
        return orderColList[i].orderType
      } else {
        return -1 * orderColList[i].orderType
      }
    }
    return 0;
  }
}

到这里,这个根据多列的排序就算完成了,我的项目中是只需要两列,但是由于操作是用户的,所以不清楚究竟他会先点击哪一列,或者是在何种状态下点击某一列,因此,我们用了一个数组记录,按照这个数组顺序作为排序的主从,从而实现了多列的排序。

网上看到的多列排序大部分都是对一个结果进行已经规定好的分别每项已什么顺序来,如果根据现在的方法,只需要在表格的items项中配置几个参数即可。