elementui 多层级table联动:
引用:
https://blog.csdn.net/weixin_44780971/article/details/130054925
https://blog.csdn.net/qq_42581563/article/details/114325920


需要了解的属性:
  • @select-all 全选的时候执行
  • @select : 选择一个的时候执行
  • default-expand-all : 默认展开所有行
  • @expand-change : 点击展开,关闭的时候执行的事件
  • :show-header : 是否展示 表头
  • :row-style : 返回每一行的style样式

多层级table联动-LMLPHP

使用 toggleRowSelection 更改子table的selection 状态的时候,必须是展开的,使用toggleRowExpansion 将expand展开

父表格的每一行都有一个子表格,,,设置父表格的名字是 main,,, 子表格的名字 是sub+scope.$index ,,每一次selection改变的时候都会传入 当前行,,通过遍历原始总数据,获取到改变的这个行的index,,,,通过这个索引可以确定你选择的子表格的 ref,,进行修改

遇到的问题:
  • this.$nextTick() :
    这个是一个异步方法,,用于在下次DOM更新循环结束之后执行回调函数,,他的作用是等待Vue实例更新DOM,,然后执行回调函数,,确保在更新完成之后再进行操作

  • 勾选的数据怎么传递出来,一般需要的都是子项的选择
    设置了一个set对象 ,,Set里面有 add ,delete,has 等方法,当勾选中的时候,就将那些子项添加进去,取消勾选,就移除,,Set对象不是响应式的,Vue不会对Set对象内容进行深层监听,,使用了一个数组去展示Set的数据,,,Vue对数组和对象的变化可以进行监听和相应
    Set怎么转换成 Array:

    • […set]
    • Array.from(set)
  • 点击展开,关闭的时候,子表格的状态都会被刷新
    @expand-change : 不能获取展开的状态是关闭还是打开,,因为 default-expand-all 最开都是打开,设置一个map存储,当点击那一行之后,将map存的值设置为关闭,根据map的值判断是否是打开,
    打开,根据之前选中存储的值,设置当前selection是否选中

  • scope.$index : 获取索引 scope.row 获取当前行

  • 插槽数据的方法:
    传入你自己的方法,可以使用插槽定义的 slot-scope 调用传入的方法
    多层级table联动-LMLPHP

  • vue方法加了括号怎么传递event

<button @click="handleClick($event)">Click me</button>

代码:

<template>
  <div>
<!--
   stripe 和   :row-class-name 不能同时存在,,同时存在显示的 stripe
   -->

    <el-table
      border
      :data="spuList"
      ref="main"
      @selection-change="handleSelectionChange"
      :row-class-name="tableRowClassName"
      height="500"
      highlight-current-row
      @current-change="handleCurrentChange"
      default-expand-all
      :row-style="tableRowStyle"
      @select-all="mainSelectAll"
      @select="mainSelect"
      @expand-change="handleExpandChange"
    >

      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-table
            :data="scope.row.skuList"
            :show-header="false"
            :row-style="tableRowStyle"
            :ref="`sub`+scope.$index"
            @select="subSelect"
            @select-all="subSelectAll"
            @selection-change="handleSubSelectionChange"

          >
            <el-table-column type="selection" width="55" ></el-table-column>
            <el-table-column type="index" ></el-table-column>
            <el-table-column prop="id" label="id"></el-table-column>
            <el-table-column prop="title" label="title"></el-table-column>

          </el-table>
        </template>
      </el-table-column>

      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column label="title" prop="title" width="200"></el-table-column>
      <el-table-column label="subtitle" prop="subtitle" width="250" show-overflow-tooltip ></el-table-column>
      <el-table-column label="createTime"  width="250">
        <template slot-scope="scope">
          {{ scope.row.createTime}}
        </template>
      </el-table-column>

    </el-table>

    <div>
    <el-button @click="toggleSelection([spuList[1],spuList[2]])">切换第二、第三行的选中状态</el-button>
    <el-button @click="toggleSelection()">取消选择</el-button>
      <el-button @click="handleToggle(spuList[0])"> btn</el-button>
      <el-button @click="setCurrent(spuList[1])">选中第二行</el-button>
    </div>


    <div class="container">
      <el-table
      :data="table">
        <el-table-column prop="id" label="id"></el-table-column>
        <el-table-column prop="title" label="title"></el-table-column>
      </el-table>
    </div>
  </div>

</template>

<script>
import {listSpu} from "@/api/cc/test";

export default {
  name: "index",
  created() {
    listSpu().then(res=>{
      console.log(res)
      this.spuList = res.list
      this.spuList.forEach(item=>{
        this.expandMap.set(item.id,true)
      })
    })
    //

  },
  data() {
    return {
      spuList:[],
      multipleSelection:[],
      subSelection:new Set(),
      expandMap:new Map(),
      table:[]
    }
  },
  methods:{
    handleExpandChange(row,expand){
      var isExpand = this.expandMap.get(row.id);
      if (isExpand){
        this.expandMap.set(row.id,false)
      }else{
        // 打开  显示children 的selection
        this.expandMap.set(row.id,true)
        this.spuList.forEach((item,index)=>{
          if (item.id === row.id){
            this.$refs.main.toggleRowExpansion(item,true)

            this.$nextTick(()=>{
              item.skuList.forEach(childItem=>{
                if (this.subSelection.has(childItem)) {
                  this.$refs[`sub${index}`].toggleRowSelection(childItem,true)
                }
              })
            })

          }
        })
      }
      console.log(row.expanded,row.selected)
      console.log(row,expand,333)
      // this.spuList.forEach((item,index)=>{
      //   if (item.id === row.id){
      //     row.skuList.forEach(item=>{
      //       if (this.subSelection.has(item)) {
      //         // this.
      //       }
      //     })
      //   }
      // })

    },
    handleSubSelectionChange(selection){
     //  selection.forEach(item=>{
     //    this.subSelection.add(item)
     //  })
     // // this.subSelection.
     //  console.log(this.subSelection,999)

    },
    subSelectAll(){
      console.log("sub all")
    },
    subSelect(selection,row){

      if (selection.includes(row)){
        // 添加
        this.subSelection.add(row)
      }else{
        // 删除
        this.subSelection.delete(row)
      }

      // 二级table 是否取消勾选,,全部都没有,就不勾选,有一个就需要勾选
      let isChecked = selection.length>0

      // console.log(selection,row,"erji")
      this.spuList.forEach((item,index)=>{
        // spu 和 sku 一对多
        if (item.id===row.spuId){

          // if (item.skuList.length === selection.length){
          //   isChecked = true
          // }else{
          //   isChecked = false
          // }
          this.$refs.main.toggleRowSelection(item,isChecked)
        }

      })

      // 将set 变成数组
      this.table = Array.from(this.subSelection)
    },
    /**
     * 改变每一个子项 的 selection
     * @param isSelection  是否选中
     */
    toggleChildStatus(isSelection){
      this.spuList.forEach((row,index)=>{
        row.skuList.forEach(item=>{
          this.$refs[`sub${index}`].toggleRowSelection(item,isSelection)
          if (isSelection){
            // 全选
            this.subSelection.add(item)
          }else{
            // 全不选
            this.subSelection.delete(item)
          }
        })
      })

      this.table = [...this.subSelection]
      // console.log(this.subSelection,777)
    },
    // toggleChildrenStatus(),

    mainSelect(selection,row){
      // console.log(selection,row,333)
    //
    //   是否选中这个元素
      var isChecked = selection.includes(row)

      console.log(isChecked,8888)


      this.spuList.forEach((item,index)=>{
        if (item.id===row.id){
          // 展开这个表格,不然会报错
          this.$refs.main.toggleRowExpansion(item,true)


          this.$nextTick(()=>{
            item.skuList.forEach((childRow)=>{
              this.$refs[`sub${index}`].toggleRowSelection(childRow,isChecked)

              if (isChecked){
                this.subSelection.add(childRow)
              }else {
                this.subSelection.delete(childRow)
              }
            })
            // this.$nextTick() 是异步的
            console.log(isChecked,[...this.subSelection],444)
            this.table = [...this.subSelection]
          })

        }
      })


      // console.log(isChecked,[...this.subSelection],555)
    },
    mainSelectAll(selection){
      console.log(selection,111)
      if (selection.length !== 0){
        // this.$refs.main.toggleRowExpansion(row,true)
       this.spuList.forEach((row)=>{
         // 勾选时要展开本行数据,,不然会找不到 子项
         this.$refs.main.toggleRowExpansion(row,true)
         this.$refs.main.toggleRowSelection(row,true)
       })


        this.$nextTick(()=>{
          // 全选
          this.toggleChildStatus(true)
        })


      }else{
        this.spuList.forEach((row)=>{
          // 取消全选也要展开
          this.$refs.main.toggleRowExpansion(row,true)
        })

        // 取消全选
        this.$refs.main.clearSelection()

        this.$nextTick(()=>{
          this.toggleChildStatus(false)
        })

      }

    },
    tableRowStyle({row,rowIndex}){
      return {
        height: '10px !important' ,// 设置每一行的高度为50px
        fontSize:"10px"
      };
    },

    setCurrent(row){
      this.$refs.main.setCurrentRow(row)
    },
    handleCurrentChange(currentRow,oldCurrentRow){
      console.log(currentRow,oldCurrentRow)
    },
    tableRowClassName({row,rowIndex}){
      // 传入一个obj 里面有 row 和 rowIndex
      if (rowIndex===1){
        return "warning-row"
      }else if (rowIndex===3){
        return "success-row"
      }
      return ""
    },
    handleToggle(row){
      this.$refs.main.toggleRowSelection(row)
    },
    toggleSelection(rows){
      if (rows){
        rows.forEach(row=>{
          this.$refs.main.toggleRowSelection(row)
        })
      }else{
        this.$refs.main.clearSelection()
      }
      console.log(rows)
    },
    handleSelectionChange(val){
      this.multipleSelection = val
    }
  }
}
</script>

<style>

.el-table .warning-row {
  background: oldlace;
}

.el-table .success-row {
  background: #f0f9eb;
}

</style>

06-05 10:12