多层级table联动

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样式

在这里插入图片描述

使用 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 调用传入的方法
    在这里插入图片描述

  • 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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/25753.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux高级---k8s中的五种控制器

文章目录 一、k8s的控制器类型二、pod与控制器之间的关系三、状态与无状态化对特点四、Deployment1、Deployment的资源清单文件2、在配置清单中调用deployment控制器3、镜像更新4、金丝雀发布5、删除Deployment 五、Statefulset六、DaemonSet1、daemonset的资源清单文件2、在配…

点到直线距离

点到直线距离最小二乘解释 推倒部分 形象描述是C到AB距离最短&#xff0c;也就是CD最短用数学语言描述是 m i n ∣ ∣ ( B − A ) λ A − C ∣ ∣ min||(B-A) \lambda A - C || min∣∣(B−A)λA−C∣∣ 其中 D ( B − A ) λ A D (B-A) \lambda A D(B−A)λA,其实本质…

使用Windbg动态调试目标进程的一般步骤及相关要点详解

目录 1、概述 2、将Windbg附加到已经启动起来的目标进程上&#xff0c;或者用Windbg启动目标程序 2.1、将Windbg附加到已经启动起来的目标进程上 2.2、用Windbg启动目标程序 2.3、Windbg关联到目标进程上会中断下来&#xff0c;输入g命令将该中断跳过去 3、分析实例说明 …

macOS Ventura 13.5beta2 (22G5038d)发布

系统介绍 黑果魏叔 6 月 1 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5 开发者预览版 Beta 2 更新&#xff08;内部版本号&#xff1a;22G5038d&#xff09;&#xff0c;本次更新距离上次发布隔了 12 天。 macOS Ventura 带来了台前调度、连续互通相机、Fac…

FPGA基于AXI 1G/2.5G Ethernet Subsystem实现千兆UDP通信 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案传统UDP网络通信方案本方案详细设计说明UDP层设计AXIS-FIFOAXI 1G/2.5G Ethernet Subsystem&#xff1a;输出 4、vivado工程详解5、上板调试验证并演示系统配置UDP数据回环测试注意事项 6、福利&#xff1a;工程代码的获取 1…

RK3588平台开发系列讲解(项目篇)RKNN-Toolkit2 的使用

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、RKNN-Toolkit2安装二、模型转换和模型推理三、性能和内存评估沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 NPU 是专门用于神经网络的处理单元。它旨在加速人工智能领域的神经网络算法,如机器视觉和自…

如何在 Linux 中进行网络地址转换 (NAT)?

网络地址转换&#xff08;Network Address Translation&#xff0c;简称NAT&#xff09;是一种在网络中使用的技术&#xff0c;它允许将私有网络中的IP地址映射到公共网络上&#xff0c;从而实现多个设备共享单个公共IP地址。在Linux系统中&#xff0c;我们可以使用一些工具和配…

《Web安全基础》01. 基础知识

基础 1&#xff1a;概念名词1.1&#xff1a;域名1.2&#xff1a;DNS1.3&#xff1a;网站开发语言1.4&#xff1a;后门1.5&#xff1a;Web1.6&#xff1a;Web 相关安全漏洞 2&#xff1a;数据包2.1&#xff1a;HTTP2.2&#xff1a;HTTPS2.3&#xff1a;请求数据包2.3.1&#xff…

MySQL 数据操纵语言 DML

文章目录 数据操纵语言 DMLINSERT 语句UPDATE 语句DELETE 语句 数据操纵语言 DML 数据操纵语言&#xff08;Data Manipulation Language&#xff0c;DML&#xff09;是 SQL 语言的核心部分之一。在添加、更新或者删除表中的数据时&#xff0c;需要执行 DML 语句。很多时候我们提…

03 【数据代理 事件处理】

03 【数据代理 事件处理】 1.数据代理 了解数据代理需要js的一些知识&#xff1a;Object.defineProperty()&#xff0c;属性标志&#xff0c;属性描述符&#xff0c;getter&#xff0c;setter。。。 1.1数据代理 建议学习文章地址&#xff1a; https://zh.javascript.info/p…

软考A计划-试题模拟含答案解析-卷十三

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

docker可视化管理工具portainer忘记密码重置教程

目录 前言&#xff1a; 1 停止portainer容器 2 借助仓库 portainer/helper-reset-password 重置密码 3 重新启动portainer容器 4 验证是否修改成功 5 修改登录密码 前言&#xff1a; 由于学习的深入&#xff0c;各种账号密码实在是太多了&#xff0c;建议各位配置账号密…

【JavaSE】Java基础语法(三十五):多线程实战

文章目录 1. 多线程入门1.1 多线程相关概念1.2 什么是多线程1.3 多线程的创建方式1.3.1 继承 Thread 的方式1.3.2 实现 Runnable 接口的方式1.3.3 实现 Callable 接口的方式1.3.4 Thread 类中常用方法1.3.5 sleep() 方法 和 wait() 方法区别&#xff1a; 2. 线程安全2.1 线程安…

机器学习算法

机器学习擅长的任务: ● 回归&#xff08;regression&#xff09; ● 分类&#xff08;classification&#xff09; ● 聚类&#xff08;clustering&#xff09; 1.回归&#xff08;regression&#xff09; 回归是处理连续数据时使用的方法&#xff0c;如时间序列数据。 …

java 利用poi根据excel模板导出数据(一)

前言 作为B端开发&#xff0c;导出数据是不可以避免的&#xff0c;但是有时候需求很变态&#xff0c;表头复杂的一笔&#xff0c;各种合并单元格&#xff0c;如下图&#xff1a; 这些虽说用代码可以实现&#xff0c;但是很繁琐&#xff0c;而且代码并不能通用&#xff0c;遇到…

Python编程面试题及答案(20例)

以下是一些常见的Python编程面试题以及它们的答案&#xff1a; 1.解释Python中的 GIL&#xff08;全局解释器锁&#xff09;是什么&#xff0c;它对多线程编程有什么影响&#xff1f; 答案&#xff1a;GIL是Python解释器中的一个机制&#xff0c;它确保在任何给定时间只有一个…

Lecture 5 Part of Speech Tagging

目录 POS application: Information Extraction 词性应用&#xff1a;信息提取 POS Open Class 开放类词性Problem of word classes: Ambiguity 词类问题&#xff1a;模糊性Tagsets 标记集Penn Treebank Tags:Derived Tags: 衍生标签Tagged Text Example 标记文本示例Reasons f…

160个CrackMe之001

吾爱中的逆向练习题 运行程序 有两个方式 一个是账号登入 一个是序列号输入 账号输入 方法一 爆破 我们先进行账号输入 这个是最简单的逆向 所以我们可以使用 字符串查找看看 先试用ollydbg打开 右键 ->查找 ->所有参考文本字符串 这里我们能发现有两个报错 我们还…

通过python封装1688图片搜索商品数据接口,拍立淘API接口

1688图片搜索API封装接口是一个可以帮助用户快速使用1688图片搜索API的接口封装库。该接口封装库可以帮助用户快速引入1688图片搜索API&#xff0c;并提供各种参数配置和封装的API调用方法&#xff0c;以方便用户快速实现自己的图片搜索需求。 该接口封装库将1688图片搜索API的…

九耶丨阁瑞钛伦特-springmvc(三)

SpringMVC作为一种流行的Java Web框架&#xff0c;是基于Spring之上的。它提供了强大的MVC&#xff08;Model-View-Controller&#xff09;架构&#xff0c;能够快速地实现Java Web开发&#xff0c;高效地与数据交互。如何使用SpringMVC成为开发人员的首要问题。要了解SpringMV…