el-table多行合并+表格行内联动多选+三级选择

el-table多行合并+表格行内联动多选+三级选择

    • 写在前面的话
    • 需要实现效果
    • 表格代码
    • 数据
    • 实现部分
    • 代码完善

写在前面的话

这几天公司前端需求做一个类似下图的功能,这个看上去像树形结构的东西,如果直接用el-tree那么结构写起来则比较简单,但是缺少了表格的韵味,那么就自己鼓捣一个,面向百度编程找到了一个老哥的博客,很像但是不全,那就试试看再加以改造,老哥原文链接element 复合表格 el-table多行合并+表格行内多列勾选el-table多行合并+表格行内联动多选+三级选择_第1张图片

需要实现效果

  • 选择一级内容时,二级三级对应项目全选
  • 取消全选时,而三级对应项目取消选择状态
  • 选择二级内容时,对应三级项目全选,若一级项目不是选中状态,则一级项目变为选择状态
  • 取消选择二级内容时,对应三级项目取消全选,若二级项目无一选中,则一级项目由选中状态变为未选中状态
  • 选择三级项目时,对应的一级、二级项目变为选中状态

表格代码

<template>
  <div>
    <el-table :data="JZPFData" ref="JZPFData" border
      :show-header= "false"
      :span-method="objectJBXXMethod" 
      height="calc(90vh - 80px)">
      <el-table-column prop="firstTitle" min-width="120">
        <template slot-scope="scope">
          <el-checkbox v-model="scope.row.firstChecked"
          @change="firstTitleChange(scope.row,scope.row.firstTitle)">
          </el-checkbox>
          {{scope.row.firstTitle}}
        </template>
      </el-table-column>
      <el-table-column prop="secondTitle" min-width="120">
        <template slot-scope="scope">
          <el-checkbox v-model="scope.row.secondChecked"
          @change="secondTitleChange(scope.row,scope.row.secondTitle)">
          </el-checkbox>
          {{scope.row.secondTitle}}
        </template>
      </el-table-column>
      <el-table-column prop="thirdTitle" min-width="180">
        <template slot-scope="scope">
          <el-checkbox v-model="scope.row.thirdChecked"
          :disabled="scope.row.isDisabled"
          @change="thirdTitleChange(scope.row,scope.row.thirdTitle)">
          </el-checkbox>
          {{scope.row.thirdTitle}}
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

数据

JZPFData: [{
	"firstChecked": true,
	"firstTitle": "首页",
	"isDisabled":false,
	"secondChecked":true,
	"secondTitle":"首页",
	"thirdChecked":true,
	"thirdTitle":"控制台"
}
...
]

实现部分

    data () {
      return {
        JZPFData: [],
        meta:{ per_page: 15, current_page: 1 },
        regroupData: [],
      };
    },
    mounted() {
      this.getTabelDate()
    },
    methods: {
      getJBXXTableData() {
        let spanOneArr = [],
          spanTwoArr = [],
          concatOne = 0,
          concatTwo = 0;
        this.JZPFData.forEach((item, index) => {
          if (index === 0) {
            spanOneArr.push(1);
            spanTwoArr.push(1);
          } else {
            if (item.firstTitle === this.JZPFData[index - 1].firstTitle) { //第一列需合并相同内容的判断条件
              spanOneArr[concatOne] += 1;
              spanOneArr.push(0);
            } else {
              spanOneArr.push(1);
              concatOne = index;
            };
            if (item.secondTitle === this.JZPFData[index - 1].secondTitle) { //第二列需合并相同内容的判断条件
              spanTwoArr[concatTwo] += 1;
              spanTwoArr.push(0);
            } else {
              spanTwoArr.push(1);
              concatTwo = index;
            };
          }
        });
        return {
          one: spanOneArr,
          two: spanTwoArr
        }
      },
      // 前行row、当前列column、当前行号rowIndex、当前列号columnIndex
      objectJBXXMethod({
        row,
        column,
        rowIndex,
        columnIndex
      }) {
        if (columnIndex === 0) {
          const _row = (this.getJBXXTableData(this.JZPFData).one)[rowIndex];
          const _col = _row > 0 ? 1 : 0;
          return {
            rowspan: _row,
            colspan: _col
          };
        }
        if (columnIndex === 1) {
          const _row = (this.getJBXXTableData(this.JZPFData).two)[rowIndex];
          const _col = _row > 0 ? 1 : 0;
          return {
            rowspan: _row,
            colspan: _col
          };
        }
      },
      firstTitleChange(row,checkVal){
        this.JZPFData.forEach(item => {
          // 如果一级选中之后,二级与三级均全选
          if(row.firstChecked==true && item.firstTitle==row.firstTitle && checkVal){
            item.secondChecked = true
            item.thirdChecked = true
          }
          if(row.firstChecked==false && item.firstTitle==row.firstTitle && checkVal){
            item.secondChecked = false
            item.thirdChecked = false
          }
        })
      },
      secondTitleChange(row,checkVal){
        // 判断二级内容勾选了几条,如果勾选条数大于0则勾选第一级,否则移除第一级
        let checkNum=0
        this.JZPFData.forEach(item => {
          if(item.firstTitle==row.firstTitle){
            checkNum+=item.secondChecked?1:0
          }
          // 勾选第二级,第三级全选,第一级选中
          if(row.secondChecked==true && row.firstTitle==item.firstTitle && checkVal){
            item.firstChecked = true
            if(item.secondTitle==row.secondTitle){
              item.thirdChecked = true
            }
          }
          if(row.secondChecked==false && row.firstTitle==item.firstTitle && checkVal){
            if(checkNum>0){
              item.firstChecked = true
            }else{
              item.firstChecked = false
            }
            if(item.secondTitle==row.secondTitle){
              item.thirdChecked = false
            }
          }
        })
      },
      thirdTitleChange(row,checkVal){
        // 判断第三级内容勾选了几条,如果勾选条数大于0则勾选第一第二级,否则移除第一第二级
        let checkNum=0
        let checkNum1=0
        this.JZPFData.forEach(item => {
          if(item.secondTitle==row.secondTitle){
            checkNum+=item.thirdChecked?1:0
          }
          if(item.firstTitle==row.firstTitle){
            checkNum1+=item.thirdChecked?1:0
          }
          // 将第三级内容勾选条对应的一级、二级内容进行勾选
          if(item.firstTitle==row.firstTitle && row.thirdChecked==true && checkVal){
            item.firstChecked=true
            if(item.secondTitle==row.secondTitle){
              item.secondChecked=true
            }
          }
        })
        // 将三级内容整组未勾选的二级内容去掉
        this.JZPFData.forEach(item => {
          if(item.secondTitle==row.secondTitle && checkNum<=0){
            item.secondChecked=false
          }
        })
        // 将三级全部未勾选的一级内容去掉
        this.JZPFData.forEach(item => {
          if(item.firstTitle==row.firstTitle && checkNum1<=0){
            item.firstChecked=false
          }
        })
      }

代码完善

自己本地上将半选状态更新完成,过两天再更新一下博客。

你可能感兴趣的:(Vue,javascript,html,vue.js,前端,elementui)