element-ui 树形表格多选

如题element-ui 2.13.2版本支持树形结构tabel,多层级折叠显示

但是没有多选 + 树形tabel, 业务需求的情况下必须要实现,操作勾选数据编辑

这里我们可以用两个事件来实现:

  @select:用户勾选某行触发事件,第一个参数selection:所有选中的数据, 第二参数row:勾选的这行数据)

  @select-all : 表头的全选、反选触发事件,只有一个参数selection:所有选中的数据

1、多选的处理函数(文档实例):

toggleSelection(rows) {
      if (rows) {
        rows.forEach(row => {
      // toggleRowSelection有两个参数,第一个是每个选中数据,第二个是点击勾选的这行是否选中,树形结构需要,不然子集选中,本身不给选中
this.$refs.multipleTable.toggleRowSelection(row, true); }); } else { this.$refs.multipleTable.clearSelection(); } },

2、现在再来处理多选和单选,调用 toggleSelection 即可

因为树形结构的数据结构不符合选中数据格式,因此需要进行过滤处理

// 采用普通表格,然后进行样式和交互处理
<el-table 
:data="tableData" 
ref="multipleTable" 
:row-class-name="tabelStyle"   // 处理折叠样式 或者使用 :row-style 注意函数返回的必须是Object
@select="rowSelect" 
@select-all="selectAll" 
align="center" 
border>
   <el-table-column type="selection" width="55"></el-table-column>
  <el-table-column prop="id" width="55">
    <template slot-scope="scope">
      <span @click="togglerShow(scope.row.id)> // 折叠图标和点击控制
        <i v-if="scope.row.children && scope.row.children.length" class="el-icon-arrow-right"></i>
        <i v-else class="el-icon-arrow-down"></i>
      </span>
      <span>{{scope.row.id}}</span>
    </template>
  </el-table-column>
  ... 
</el-talbe>

// js
methods: {
  tabelStyle({row, rowIndex}) {
    const show = row.show ? true : false
    return show ? 'tr-show' : 'tr-hide'
  },
 togglerShow(val) {
      this.tableData.map(item => {
        if (item.id=== val) {
          item.country= item.country+ ' '  // 预发不重新渲染数据
          if (item.children && item.children.length) {
            item.expanded = !item.expanded
          } else {
            item.show = !item.show
          }
        }
      })
    }
 }
 
 // scss
 <style lang="scss">
  .tr-show {
    animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;
  }
  .tr-hide {
    display:none;
  }
 </style>
// 模拟数据源 
data = {
  list: [
    {
      "id": "11",
      "country": "Australia",
      "enable": "1",
    "region_id": '11',
"children": [ { "id": "151", "country": "Capital",
      "region_id": '11',
"enable": "1" }, { "id": "152", "country": "Territory",
      "region_id": "11",
"enable": "0", }, { "id": "153", "country": "Northern Territory",
      "region_id": "11",
"enable": "0" }, { "id": "154", "country": "Queensland",
      "region_id": "11",
"enable": "1" }, { "id": "155", "country": "South Australia",
      "region_id": '11',
"enable": "1" } ] }, { "id": "58", "country": "Austria",
    "region_id": "12",
"enable": "1" }, { "id": "331", "country": "Azores",
    "region_id": "13",
"enable": "0" } ], message: "success", status: 200 }

 

简单的template 结构和模拟的数据源差不多,如上所示,children 包裹分层级

3、过滤函数 filterSelect, 选中的多层级需要处理数据才能实现正确的交互,即将层级里面children的数据依次取出来,组成数组 tableData, 即渲染的数据源

data() {
    return {
        tableData: [],
        level: 1
    }
}
// methods 中获取到的数据源要经过这层过滤处理
filterSelect(data) {
  data.forEach(item => {
    item.level = String(this.level)  // 层级
    item.show = this.level === 1 ? true : false  // 判断是否折叠
    item.isChecked = false;  // 判断是否勾选重要参数

    this.tableData.push(item)  // 收集过滤后的数据,将children数据全部取出来
    if (item.children && item.children.length > 0) {
      item.expanded = true // 顶层下有折叠
      item.show = true  // 顶层显示
      this.level++
      this.recursionArr(item.children)
    }
  });
}

 

4、实现符合逻辑的勾选交互

表头全选函数:

selectAll(selection) {  // selection 是选中的数据集合
  this.tableData.map(item => {
    item.isChecked = !item.isChecked  // 处理每条数据isChecked 选择状态
  })
}

单行(多层级,目前只做了二级)全选、单选:

rowSelect(selection, row) {
      let changeArr = []
      if (row.level === '1') {
        if (row.isChecked) {
          selection.map(item => {
            if (row.region_id !== item.region_id) {
              changeArr.push(item)
            } else {
              this.$refs.multipleTable.toggleRowSelection(item)
            }
          })
        } else {
          this.tableData.map((item,index) => {
            if (row.region_id === item.region_id) {
              changeArr.push(item)
            }
          })
          changeArr = changeArr.concat(selection)
        }

      } else if (row.level === '2') {
        changeArr = selection
        if (!row.isChecked) {
          this.tableData.map(item => {
            if (row.region_id === item.region_id && item.level === '1') {
              changeArr.push(item)
            }
          })
        }
      }

      changeArr = [...new Set(changeArr)]   // 去重
       
      // 更新isChecked 状态
      this.tableData.map(item => {
        if (item.id === row.id) {
          item.isChecked = !item.isChecked
        }
      })

      // 正反选
      if (changeArr.length) {
        this.toggleSelection(changeArr)
      } else {
        // 清除所有
        this.$refs.multipleTable.clearSelection();
      }
    }    

 

以上就可以实现多选树形结构的操控

注: 如有需要参考的,请注意源数据模型和template结构中的参数配置,全选(多层级)、单选、过滤这三个函数,注意里面的数据源变量名this.tableData,目前多选、单选只做了两层级,有兴趣的同学可以补充完整

 

posted @ 2020-07-20 14:52  浪里小韭菜  阅读(7083)  评论(0编辑  收藏  举报