Vue+Elenment el-table树复选框,半选全选

1,026 阅读1分钟

完整代码

<template>
   <el-table :data="tableData"
    ref="tableRef"
    row-key="id"
    :indent="10"
    v-loading="menuLoading"
    show-checkbox
    select-on-indeterminate=""
    :tree-props="{children: 'children'}"
    node-click
    @select-all="selectchageall"
    border
    >
            <el-table-column
              type="selection"
              align="center"
              width="50px" 
              >
              <template slot-scope="scope">
                <el-checkbox v-model="scope.row.IsClick" :indeterminate="scope.row.isIndeterminate" @change="handleCheckrow(scope.row)" />
              </template>
            </el-table-column>
            <el-table-column
              prop="menuName"
              label="名称"
              header-align="center"
              width="300px">
            </el-table-column>
            <el-table-column
              prop="id"
              label="菜单编码"
              :show-overflow-tooltip="true"
              width="180">
              </el-table-column>
              <el-table-column
              prop="parentMenuName"
              label="父菜单"
              width="180">
              </el-table-column>
              <el-table-column
                label="类型"
                width="100">
                <template slot-scope="scope">{{ scope.row.menuType===0?'根菜单':scope.row.menuType===1?'页面':scope.row.menuType===2?'按钮':'' }}</template>
              </el-table-column>
          </el-table>
 </template>
 <script>
     export default {
         data(){
            return {
              menuLoading:false,
              menuIds:[], // 选中数据的ids 做回显用
              tableData:[
                  {
                    id:1,
                    menuName: '首页',
                    IsClick: false,
                    IsInDM: false,
                    parentMenuName:'根目录',
                    menuType:1
                  },
                   {
                    id:2,
                    menuName: '商品',
                    parentMenuName:'根目录',
                    IsClick: false,
                    IsInDM: false,
                    menuType:1
                    children:[
                        {
                            id:2-1,
                            parentMenuName:'商品',
                            menuName: '普通商品管理',
                            IsClick: false,
                            IsInDM: false,
                            menuType:1
                          }
                    ]
                  }
                
              ],
              selectallcilck:false,//table的全选
              thisdataAray: [],//储存的全部数据
              isAllClick:null,//全选还是全不选
            }
         },
         methods:{
            handleCheckrow(row) {
              // 全选、全不选
              // 设定全选全不选的选择值
              this.isAllClick = row.IsClick
              //清空数组
              this.thisdataAray = []
              // 给数组添加遍历出来的的全部数据
              this.addpushdata(this.tableData)
              this.thisdataAray.forEach((item) =>{
                if (item.id == row.id) {
                  if (item.children && item.children.length > 0) {
                    this.ifAllSelection(item.children)
                  }
                }
              })
              // 子级选择
              if (row.children && row.children.length > 0) {
                this.issoncheckin(row)
              }
              // console.log(row)
              // 判定父级的是否半选全选
              this.ifSelection(this.tableData)
              // 给el-table添加选中的列
              this.inSelection()
              console.log(this.tableData)
            },
            // 功能:判定全选
            ifAllSelection(item){
              // 将数据循环判断
              item.forEach((itemdata) => {
                //如果有子级则继续循环
                if (itemdata.children && itemdata.children.length > 0) {
                  this.ifAllSelection(itemdata.children)
                }
                // debugger
                // 如果没有子级则设置为全选设定
                if (!itemdata.children || itemdata.children.length === 0) {
                  itemdata.IsClick = this.isAllClick
                }
              })
            },
            // 功能:在点击时判定父类的子类是否被选中为半选
            ifSelection(item){
              //  console.log(item)
              item.forEach((itemdata) => {
                if (itemdata.children && itemdata.children.length > 0) {
                  this.ifSelection(itemdata.children)
                  this.issoncheckin(itemdata)
                  // console.log(itemdata)
                }
                // console.log(itemdata)
              })
            },
            // 功能:给el-table添加选中的列
            inSelection(){
              //清空数组
              this.thisdataAray = []
              // 给数组添加遍历出来的的全部数据
              this.addpushdata(this.tableData)
              // 给全部数据设定是否被选中
              this.thisdataAray.forEach((item)=>{
                // 设定选中的列
                this.$refs.tableRef.toggleRowSelection(item,item.IsClick);
              })
            },
            // 功能:给与树状列表半选和选定状态
            issoncheckin(item){
              // Some和Every对数组的遍历: this.issoncheckin(item)
              // some是数组中只要有一个符合条件就返回true。
              // every是每一个元素都符合条件才返回true,否则返回false。
              // 子项都选中every遍历每一个子类符合条件就返回true,条件:子类的IsClick。用以判断子类全部选中,
              const all = item.children.every(flag => flag.IsClick)
              // 如果子类被全部选中则选中
              if (all) {
                // 选中
                item.IsClick = true
                // 半选
                item.IsInDM = false
                item.isIndeterminate = false
              }
              // 如果有一个子类符合条件了则
              const some = item.children.some(flag => flag.IsClick)
              const sonsome = item.children.some(flag => flag.IsInDM)
              // 部分选中半选择状态
              if (some) {
                // 再确认all全选为假
                if (!all) {
                  item.IsClick = false
                  item.IsInDM = true
                  item.isIndeterminate = true
                }
              } else if (sonsome) {
                 if (!all) {
                  item.IsClick = false
                  item.IsInDM = true
                  item.isIndeterminate = true
                 }
              } else {
                // 三都为假则不选
                item.IsClick = false
                item.IsInDM = false
                item.isIndeterminate = false
              }
            },
            // 功能:将所有的数据列出来
            addpushdata(tabData){
              tabData.forEach((indata) => {
                this.thisdataAray.push(indata)
                if (indata.children && indata.children.length > 0) {
                  this.addpushdata(indata.children)
                }
              })
            },
            // 功能:全选框选择全部行,包括树状数据的子级别。
            selectchageall(){
              // 获取真假值默认
              this.selectallcilck = !this.selectallcilck
              // 清空数组
              this.thisdataAray = []
              // 给数组添加遍历出来的的全部数据
              this.addpushdata(this.tableData)
              this.thisdataAray.forEach((item) =>{
                // 给数组的数据添加真假值
                item.IsClick = this.selectallcilck
                if(this.selectallcilck){
                  item.isIndeterminate = !this.selectallcilck
                  item.IsInDM = !this.selectallcilck
                }else{
                  item.isIndeterminate = this.selectallcilck
                  item.IsInDM = this.selectallcilck
                }
              })
              // 给与tableData中所有行附加指定真假选定值
              this.splite(this.tableData,this.selectallcilck)
            },
            // 功能:给选中行添加选中状态,如果选中行有子级也给子级添加选中状态
            splite(data,flag){
              data.forEach((row) => {
                this.$refs.tableRef.toggleRowSelection(row,flag);
                // 如果这列中有子级别(子级不为空)则对其运行一次该方法设定其是否选中。
                if (row.children && row.children.length > 0) {
                  this.splite(row.children,flag)
                }
              });
            },
             // 拿到数据后进行回显的递归设置选中
            setChecked(list){
              if(this.menuIds && this.menuIds.length > 0){
                // 先循环把最后一级选择
                list.forEach(row => {
                  if(this.menuIds.includes(row.id)){
                    // 设置当前是全选还是半选
                    // 如果有子级就继续递归
                    if(row.children && row.children.length > 0){
                      this.setChecked(row.children)
                      // 判定父级的是否半选全选
                      this.ifSelection(this.tableData)

                      // this.issoncheckin(row)
                    }else{
                      row.IsClick = true
                    }
                  }
                })
                // 设置
                this.inSelection()
              }
            },
         }
     }
 </script>