elementUI表格树动态合并列问题处理(最终版,---新需求)

在之前的一篇博客中针对这个问题,写了解决方法。现在是加了新需求,发现之前的算法有一些不足之处,现在进行纠正。

目前表格的需求是:

       评估人/评估分数/加减分说明,这个组合,根据评估人相同,就列合并;指标项目,评估人是为空的,这个组合都不合并;

      处理人/处理分数/加减分说明,这个组合,是动态表头,有可能只有一个组合,也有可能有2个组合,也有可能是3个组合;处理人是全合并,处理分数/加减分说明是指标项目,不合并,非指标项目全合并。

实现的效果图如下:

具体实现代码如下:(这里是以弹窗为例的。也可以不写在弹窗中。)

<template>
  <div style="height: 70%;">
    <el-row :gutter="20">
      <el-col :span="6"
              style="padding-top:5px;">
            <span>考核周期:
              <span>2019年11月考核</span>
            </span>
      </el-col>
      <el-col :span="4">
        <span>姓名:<span>张三</span></span>
      </el-col>
    </el-row>
    <el-row style="margin-top:20px;">
      <el-table :data="tableData1"
                ref="table"
                height="100%"
                :span-method="objectSpanMethod"
                :summary-method="getSummaries"
                :show-summary="true"
                style="width: 100%;margin-bottom: 20px;"
                default-expand-all
                row-key="id"
                @expand-change="expandChange"
                border
                class="showAll" size="small">
        <el-table-column width="200px"
                         prop="objectName"
                         label="名称">
        </el-table-column>
        <el-table-column prop="workStatus"
                         align="center"
                         width="60px"
                         label="状态"
                         show-overflow-tooltip>
          <template  slot-scope="scope">
            <span v-if="scope.row.workStatus=='1'">{{"提前"}}</span>
            <span v-else-if="scope.row.workStatus=='2'">{{"正常"}}</span>
            <span v-else-if="scope.row.workStatus=='3'">{{"滞后"}}</span>
            <span v-else-if="scope.row.workStatus=='4'">{{"已完成"}}</span>
            <span v-else-if="scope.row.workStatus=='5'">{{"暂停"}}</span>
            <span v-else-if="scope.row.workStatus=='6'">{{"中止"}}</span>
            <span v-else-if="scope.row.workStatus=='7'">{{"未启动"}}</span>
          </template>
        </el-table-column>
        <el-table-column width="65px"
                         prop="workProgress"
                         align="center"
                         label="进度(%)">
        </el-table-column>
        <el-table-column width="45px"
                         prop="timelong"
                         align="center"
                         label="工时">
        </el-table-column>
        <el-table-column width="80px"
                         prop="weight"
                         align="center"
                         label="权重(%)">
        </el-table-column>
        <el-table-column width="80px"
                         prop="selfRating"
                         align="center"
                         label="自评分">
        </el-table-column>
        <el-table-column prop="selfDiffScoreDescribe"
                         width="150px"
                         label="加减分说明">
        </el-table-column>
        <el-table-column prop="remarks"
                         width="350px"
                         label="工作内容">
        </el-table-column>
        <el-table-column prop="name"
                         label="评估人">
        </el-table-column>
        <el-table-column prop="kpiScore"
                         label="评估分数">
        </el-table-column>
        <el-table-column prop="assesseDiffScoreDescribe"
                         label="加减分说明"
                         width="300">
        </el-table-column>
        <el-table-column v-for="(item,index) in columns"
                         :key="index"
                         :label="item.label"
                         :prop="item.value"
                         :width="item.width"
        >
        </el-table-column>
      </el-table>
    </el-row>
  </div>
</template>

<script>
  export default {
    name: 'table-col',
    props: {
      // 弹窗是否打开
      visible: {
        type: Boolean,
        required: false,
        default: false
      },
      // 打开弹窗传递的id
      rowID: {
        type: String,
        required: false,
        default: ''
      }
    },
    created () {
    },
    data () {
      return {
        allRowNum:0, // 所有项目的行数
        spanArrSum:0, //非指标项目的行数
        spanArrFirstSum:0, //首次进入非指标项目的行数
        spanArrSumArr:[], // 处理分数、加减分说明等col合并数组
        allRowNumArr:[], // 处理人col合并数组
        spanArr: [], // 表格动态变化过程中的col合并数组
        objectListTable: [], // 非指标项目集合
        // 处理人数据集合
        handlerInfoList: [
          {approverDiffScoreDescribe1: null,approverName1: "张三",level1: 0,score1: 100},
          { approverDiffScoreDescribe1: null, approverName1: '谌小仲', level1: 0, score1: 100 },
          { approverDiffScoreDescribe1: null, approverName1: '王五', level1: 0, score1: 100 },
        ],
        tableData1: [], // 表格数据
        
      };
    },
    watch: {
      visible: {
        handler(n) {
          if (n) {
            this.objectListTable = [] // 非指标项目集合
            this.columns= [] // 动态表头
            this.tableData1 = [] // 表格数据绑定
            this.spanArrSum = 0; // 非指标项目的行数
            this.spanArrFirstSum = 0; // //首次进入非指标项目的行数
            this.allRowNum = 0  //所有项目的行数
            this.tableData1 = this.tableData  // 请求回来的数据赋值给this.tableData1
            // 为表格中的数据都增加一个show字段,用于判断树是否显示
            this.tableData1.forEach((item, index) => {
              item.show = true
              if(item.children){
                this.allRowNum += (item.children.length+1)
              }
              if(item.isFixed == false){
                this.objectListTable.push(item)
              }
            })
            let arrObject = []
            this.objectListTable.forEach((item, index) => {
              arrObject.push(item)
              if (item.children ) {
                this.spanArrSum += (item.children.length+1)
                this.spanArrFirstSum += (item.children.length+1)
                item.children.forEach((it, index) => {
                  arrObject.push(it)
                })
              }
            })
           // 调用表格数据合并的计算方法
            this.setdates(arrObject)
            this.handlerInfoList.forEach((item,index) => {
              console.log(item,'item1111111')
              var approverName = 'approverName' + (index + 1);
              var score = 'score' + (index + 1);
              var approverDiffScoreDescribe = 'approverDiffScoreDescribe' + (index + 1)
              this.columns.push({ label: '处理人', value: approverName, width: '100px' })
              this.columns.push({ label: '处理分数', value: score, width: '100px' })
              this.columns.push({ label: '加减分说明', value: approverDiffScoreDescribe, width: '100px' })
            })
          }
        },
        deep: true,
        immediate: true
      },
    },
    methods: {
      /** elementUI表格绑定的合并方法 */
      objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
        if (columnIndex === 8 || columnIndex === 9 || columnIndex === 10) {
          let _row = this.spanArr[rowIndex]
          if (rowIndex < this.spanArrFirstSum) {
            if (_row) {
              return {
                rowspan: _row == 99 ? 0 : _row,
                colspan: _row==99 ?0:1
              }
            } else {
              return {
                rowspan: 0,
                colspan: 0
              }
            }
          }
          else{
              return {
                rowspan: 1,
                colspan: 1
              }
          }
        }
        else if (columnIndex === 11 || columnIndex === 14 || columnIndex === 17) {
          let row2 = this.allRowNumArr[rowIndex]
          return {
            rowspan: row2,
            colspan: 1
          }
        }
        else if ((columnIndex === 12 || columnIndex === 13 || columnIndex === 15 ||
          columnIndex === 16 || columnIndex === 18 || columnIndex === 19)) {
          if (rowIndex < this.spanArrFirstSum) {
            let _row1 = this.spanArrSumArr[rowIndex]
            // console.log(_row1,'ffffffffff_row1')
            return {
              rowspan: _row1,
              colspan: 1
            }
          } else{
            return {
              rowspan: 1,
              colspan: 1
            }
          }
        }
      },
      /**  合计方法 */
      getSummaries (param) {
        const { columns, data } = param;
        const sums = [];
        columns.forEach((column, index) => {
          if (index === 0) {
            sums[index] = '合计';
            return;
          }
          let values = []
          data.map(item => {
            values.push(Number(item[column.property]))
            if (item.children) {
              item.children.map(it => {
                values.push(Number(it[column.property]))
              })
            }
          });
          if (!values.every(value => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr);
              if (!isNaN(value)) {
                return prev + curr;
              } else {
                return prev;
              }
            }, 0);
            sums[index] += 0;
          } else {
            // sums[index] = '';
            // sums[index].toString()
          }
        });

        for (var i = 0; i < sums.length; i++) {
          if (i === 5 || i === 4 || i === 0) {
            sums[i] = sums[i]
          } else {
            sums[i] = ''
          }
        }
        return sums;
      },
      /** 表格中树展开或关闭触发事件 */
      expandChange (row, expandedRows) {
        let arrObject = [] // 接收表格中树数据的转化
        this.spanArr = [] // 合并表格行数rowspan数据集合
        this.objectListTable.forEach((item, index) => { // objectListTable是排除不合并表格数据的集合
          // show字段主要是用来区分当前表格中哪些树是展开的
          if (row.id === item.id) {
            // 如果是当前点击的行,就将当前是否展开的属性赋值给show这个字段
            item.show = expandedRows
          }
          // 得到表格中需要合并数据的集合
          arrObject.push(item)
          // 如果字段show为true(树展开)
          if (item.show) {
            item.children.forEach((it, index) => {
              arrObject.push(it)
            })
          } else {

            // 节点是关闭状态  如果数据存在子节点
            if (item.children) {
                // 其他情况,push任意值进数组,但不能不push
                item.children.forEach((it, index) => {
                  arrObject.push(22)
                })
              }
            }
        })
        // 获取上半部分需要合并的行数
        if (!row.isFixed) {
          if (row.show) {
            this.spanArrSum += row.children.length
          } else {
            this.spanArrSum -= row.children.length
          }
        }
        // 获取当前表格所呈现出来的所有行数,即处理人需要合并的行数
        if(expandedRows){
          this.allRowNum += row.children.length
        }else {
          this.allRowNum -= row.children.length
        }
        // 调用合并列数的方法  0 为不合并
        this.setdates(arrObject)
      },
      /** 合并列数的方法 */
      setdates: function (arr) {
        console.log(arr, '合并列数方法中拿到的数组')
        // 转化数组,得到name的集合,如果name不存在,代表需要隐藏,这时候用22这个数字进行代替
        var kpiObjArr = []
        for (var i = 0, len = arr.length; i < len; i++) {
          if (arr[i] == 22) {
            kpiObjArr.push(22)
          } else {
            kpiObjArr.push(arr[i].name)
          }
        }
        console.log(kpiObjArr, 'kpiObjArrkpiObjArrkpiObjArrkpiObjArr')
        this.spanArrSumArr = [] // 清空处理分数、加减分说明等col合并数组
        // 获取处理分数、加减分说明等col合并数组
        for(let i =0 ; i < this.spanArrSum ; i++){
          if(i===0){
            this.spanArrSumArr.push(this.spanArrSum)
          }else{
            this.spanArrSumArr.push(0)
          }
        }
        this.allRowNumArr = [] // 清空处理人col合并数组
        // 获取处理人col合并数组
        for(let i =0 ; i < this.allRowNum ; i++){
          if(i===0){
            this.allRowNumArr.push(this.allRowNum)
          }else{
            this.allRowNumArr.push(0)
          }
        }
        // 获取最终的col合并集合
        this.spanArr = this.arrFunction(kpiObjArr,0)
      },
      /** 数组数据处理方法 */
      arrFunction(list,index){
          var a=0;
          var reg = new RegExp("[\\D]");
          for (var i=index;i<list.length;i++){
            if( reg.test(list[i])){
              a=i;
              break;
            }
          }
          var s=index;
          for (var i=index+1;i<list.length;i++){
            s++; //记录终结点
            if(list[a]==list[i]){
              list[i]=0;
            }else if(reg.test(list[i])&&list[a]!=list[i]){
              break;
            }
          }
          var count=0;
        list[index] = 1
          for (var i = index + 1; i < list.length; i++) {
            if (list[i] ==0) {
              count++;
              list[i] = 22;
              list[index+count] = 0;
              list[index]=count+1;
            }
            if(list[i]==22){
              list[i] = 99;
            }
          }
          if(s<list.length-1){
            list=this.arrFunction(list,s);
          }
          return list;
      }
    }
  }
</script>

<style lang="scss" scoped>
</style>

代码到此就完成了。

其中需要注意的就是row与col的合并,上面代码中,例入spanArr=[1,99,99,3,0,0]     99就代表row为0,col也为0,是被收起来的树节点的子节点,需要被隐藏掉;这种场景代表项目1为关闭,隐藏项目1下的子节点,项目2为打开,col需要合并为3,0,0,row都为1,0代表的是col此时不合并。

需要注意的第二点就是:当得到的人名组合为kpiObjArr=[a,22,22,b,b,b],如何将这个数组变为[1,99,99,3,0,0]这样的格式,22上述代码中已写过备注,代表被收起来的子节点,需要被隐藏。【kpiObjArr的场景非常多,这里再说几个例子 :

kpiObjArr=[a,22,22,a,a,a,b,b,b]          --------------------------------------------------spanArr=[4,0,0,0,99,99,3,0,0]

kpiObjArr=[a,22,22,a,22,22,b,22,22]------------------------------------------------------spanArr=[2,0,99,99,99,99,1,99,99]

需要找到规律,来将这个数组进行转化成功,最后再表格自带的合并方法中进行渲染,

下面补充一下,后台返回的tableData的数据格式(数据多,所以没有写在上面进行定义)

// 后台返回的表格数据
tableData: [
  {
    id: '1191670059258875904',
    isFixed: false,
    approverName1: '张三',
    approverName2: '王五',
    approverName3: '李四',
    approverDiffScoreDescribe1: '',
    approverDiffScoreDescribe2: '',
    approverDiffScoreDescribe3: '',
    score1: 100,
    score2: 100,
    score3: 100,
    kpiScore: 99,
    name: "王五",
    num: 2,
    objectName: "项目1",
    remarks: null,
    selfRating: null,
    timelong: null,
    weight: null,
    workProgress: null,
    workStatus: null,
    assesseDiffScoreDescribe: 'null',
    children:[
      {
        id: "11916698122256666",
        name: "王五",
        objectName: "工作项1",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '',
        approverName2: '',
        approverName3: '',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: null,
        score2: null,
        score3: null,
      },
      {
        id: "2222222333322999999",
        name: "王五",
        objectName: "工作项2",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 100,
        score2: 100,
        score3: 100,
      }
    ]
  },
  {
    id: '11916700592588759042',
    isFixed: false,
    approverName1: '张三',
    approverName2: '王五',
    approverName3: '李四',
    approverDiffScoreDescribe1: '',
    approverDiffScoreDescribe2: '',
    approverDiffScoreDescribe3: '',
    score1: 100,
    score2: 100,
    score3: 100,
    kpiScore: 88,
    name: "王五",
    num: 2,
    objectName: "项目2",
    remarks: null,
    selfRating: null,
    timelong: null,
    weight: null,
    workProgress: null,
    workStatus: null,
    assesseDiffScoreDescribe: 'null333',
    children:[
      {
        id: "119166981222566662",
        name: "王五",
        objectName: "工作项1",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '',
        approverName2: '',
        approverName3: '',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: null,
        score2: null,
        score3: null,
      },
      {
        id: "22222223333229999992",
        name: "王五",
        objectName: "工作项2",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 100,
        score2: 100,
        score3: 100,
      },
      {
        id: "00000000002",
        name: "王五",
        objectName: "工作项3",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 100,
        score2: 100,
        score3: 100,
      }
    ]
  },
  {
    id: '11916700592588759042a',
    isFixed: false,
    approverName1: '张三',
    approverName2: '王五',
    approverName3: '李四',
    approverDiffScoreDescribe1: '',
    approverDiffScoreDescribe2: '',
    approverDiffScoreDescribe3: '',
    score1: 100,
    score2: 100,
    score3: 100,
    kpiScore: 100,
    name: "aaa兰",
    num: 2,
    objectName: "项目3",
    remarks: null,
    selfRating: null,
    timelong: null,
    weight: null,
    workProgress: null,
    workStatus: null,
    assesseDiffScoreDescribe: null,
    children:[
      {
        id: "119166981222566662a",
        name: "aaa兰",
        objectName: "工作项1",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '',
        approverName2: '',
        approverName3: '',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: null,
        score2: null,
        score3: null,
      },

      {
        id: "00000000002a",
        name: "aaa兰",
        objectName: "工作项2",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 100,
        score2: 100,
        score3: 100,
      }
    ]
  },
  {
    id: '9',
    isFixed: true,
    approverName1: '',
    approverName2: '',
    approverName3: '',
    approverDiffScoreDescribe1: '',
    approverDiffScoreDescribe2: '',
    approverDiffScoreDescribe3: '',
    score1: null,
    score2: null,
    score3: null,
    kpiScore: '',
    name: "",
    num: 2,
    objectName: "指标项目1",
    remarks: null,
    selfRating: null,
    timelong: null,
    weight: null,
    workProgress: null,
    workStatus: null,
    assesseDiffScoreDescribe: null,
    children:[
      {
        id: "99",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 50,
        score2: 40,
        score3: 60,
        name: "",
        objectName: "指标1",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        kpiScore: '',
      },
      {
        id: "999",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 101,
        score2: 102,
        score3: 103,
        name: "",
        objectName: "指标2",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        kpiScore: '',
      }
    ]
  },
  {
    id: '91',
    isFixed: true,
    approverName1: '',
    approverName2: '',
    approverName3: '',
    approverDiffScoreDescribe1: '',
    approverDiffScoreDescribe2: '',
    approverDiffScoreDescribe3: '',
    score1: null,
    score2: null,
    score3: null,
    kpiScore: '',
    name: "",
    num: 2,
    objectName: "指标项目2",
    remarks: null,
    selfRating: null,
    timelong: null,
    weight: null,
    workProgress: null,
    workStatus: null,
    assesseDiffScoreDescribe: null,
    children:[
      {
        id: "991",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 50,
        score2: 40,
        score3: 60,
        name: "",
        objectName: "指标项1",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        kpiScore: '',
      },
      {
        id: "9991",
        approverName1: '张三',
        approverName2: '王五',
        approverName3: '李四',
        approverDiffScoreDescribe1: '',
        approverDiffScoreDescribe2: '',
        approverDiffScoreDescribe3: '',
        score1: 101,
        score2: 102,
        score3: 103,
        name: "",
        objectName: "指标项2",
        remarks: "垃圾数据22019-11-05周报:已完成",
        selfDiffScoreDescribe: null,
        selfRating: 100,
        timelong: 8,
        weight: 100,
        workProgress: 100,
        workStatus: "4",
        kpiScore: '',
      }
    ]
  },
],
发布了38 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CuiCui_web/article/details/103767614