elementUI中table动态列以及动态列排序

16,736 阅读3分钟

关于elmentUI的普通表格排序没有啥好说的, 但是在实际项目过程中有时候是需要动态列的,动态列也就意味着prop字段的不确定,动态列的排序也会因为没有字段而无法处理,而我们需要完成动态列以及对动态列根据不同情况排序【前端排序】

动态列

目前遇到的项目是表格可能根据年度/季度/月度而会有不同的列数,比如年度有【2020年,2019年,...】,季度【2020-4季度,2020-3季度,...】,月度【2020-12月,2020-11月...】,并且每种类型的字段并不确定,比如年份有可能2年,有可能3年,有可能6年,这就需要多列动态了,另外因为列是动态,那么后台取回的对应的属性和表头值都是数组,而不会是单独的值

动态列实现方案一(列不需要排序可选)

动态列定义成一个动态的数组,数组中只存放从后台请求过来的表头值,比如 [2019-10, 2019-9,2019-8], 对于表格的数据会把数组中的数组作为字符串处理,拿不到具体的数值,需要用filter将数据处理为对应的数据,相关实现代码如下


 <template>
    <el-table :data="dataList" >
      <!-- 动态生成列 -->
      <el-table-column
        v-for="(item,index) in theadList"
        :key="index"
        :label="item"
        prop="colprops"
        align="center"
      >
        <template slot-scope="scope">
          <div>{{ scope.row.colprops | transToValue(index)) }}</div>
        </template>
       </el-table-column>
      <!-- 动态生成列结束 -->
    </el-table>
 <template>
 
<script>
    export default {
      filters: {
        transToValue(val, index) {
          return val[index]
        }
      },
      data() {
        return {
          theadList: [],
          dataList: []
        }
      },
      methods: {
        queryList(){
             const data = {...}
             this.$http.post(data).then(res => {
                // 对表头进行赋值处理 res.dataArr中包含表头数组 例如[2019,2018,2017,2016]
                this.theadList = res.dateArr
                //res.rows中每项的colprops属性中包启有所有表头[2019,2018,2017,2016]列对应,用filter后就可以将对应的值取出处理
                //如res.rows[0]为一个{
                //    colprops: ['8%', '9.6%', '6.4%', '6%'],
                      otherVal: 'xxxx'
                //}
                this.dataList = res.rows
              }).catch(err => { ...})
        }
      }         
    }   
<script> 

动态列实现方案二(列需要排序必选)

因为要实现排序,方案一无法拿到对应列的属性,无法对动态列的每一项单独进行排序,所以就有了方案二,方案一能解决动态数据展示的问题,方案二能让表格动态列与普通列一样使用各种方法进行排序,原理就将动态不确定的列给对应的属性值,让其它能用属性值进行赋值操作 表头数组项的每一项变成{label: 'collabel', props: 'colProps'}然后每一项数据的属性为colProps的值拿到即可,附源码如下

<template>
    <!-- 表格list -->
    <el-table :data="dataList" border @sort-change="changeTableSort">
      <!-- 动态生成列 -->
      <el-table-column
        v-for="(item,index) in theadList"
        :key="index"
        :label="item.label"
        :prop="item.prop"
        :sortable="'custom'"
      >
      <!--如果数据还需要处理,否则不用以下代码-->
        <template slot-scope="scope">
          <div>{{ scope.row[item.prop] | toFixed(6) }}</div>
        </template>
      </el-table-column>
      <!-- 动态生成列结束 -->
    </el-table>
</template>

<script>
export default {
  data() {
    return {
      // 动态列表头及属性
      theadList: [{ label: '', prop: '' }],
      dataList: []
    }
  },
  mounted() {
    this.queryList()
  },
  methods: {
    queryList() {
      const data = {...}
      this.$http.post(data).then(res => {
        this.loading = false
        // 对表头进行赋值处理 prop中的tr[index]与 datalist中的item项的 item['tr'+ i]一一对应
        this.theadList = res.dateArr.map((item, index) => { 
          return { 
              label: item, 
              prop: 'tr' + index 
          } 
        })
        // 对表头对应的每一列的属性进行赋值
        // 为了能正常排序 需要对所有的数值进行处理 【如果有需要数字型进行排序null或者空字付串的数值请处理为0】
        this.dataList = res.rows
        this.dataList.forEach(item => {
          for (let i = 0; i < res.dateArr.length; i++) {
            item['tr' + i] = item.rateArr[i] || '0'
          }
        })
      }).catch(err => {... })
    },
    // 排序列改变返回当前需要排序的列
    changeTableSort(e) {
      //获取当前列的字段
      const prop = e.prop
      // 如果按降序
      if (e.order === 'descending') {
        //根据需要对字段进行写排序
        this.dataList = this.dataList.sort((a, b) => {
          return parseFloat(a[prop]) - parseFloat(b[prop])
        })
      } else { //发果是降序
        this.dataList = this.dataList.sort((a, b) => {
          return parseFloat(b[prop]) - parseFloat(a[prop])
        })
      }
    }
  }
}
</script>

动态列排序

  1. 动态列如果需要排序,那么props必须有动态的属性值,既然是动态列,固定属性是肯定不存在的,那么需要我们自已自定义字段属性供表格使用
  2. 表头中自定义的属性字段与数据中自定义的属性字段相互匹配 比如表头定义为 cols1, cols2, cols3, 那么数据列表单项就有匹配的属性与值相对应,比如
const = theadList = [
    {label: '2019年', prop: 'cols1'},
    {label: '2018年', prop: 'cols2'}
]
const  dataList = [{
    cols1: 'xxx',
    cols2: 'xxxx',
}]
  1. 在使用changeTableSort进行排序时,如果是进行数值大小排序,如果有值为null, ''之类的值,需要先处理为0后再进行比较,否刚排序的方法可能会失效
  2. 数值排序方法都正确,但是排序还是有问题,刚请检查是否设置:sortable="'custom'"
  3. 附源码图