element-ui树形表格,左边勾选,右边显示选中的数据-功能(如动图)
功能如图


功能需求
表格树形表格勾选数据,右边显示对应勾选的数据内容,选中客户,自动勾选所有的店铺(子级),选中其中一个店铺,自动勾选上客户(父级),同时会存在只有客户(下面没有子级的情况),该功能还涉及到全选(不细讲),搜索勾选,搜索其中一个店铺,或者搜索客户显示所有店铺在勾选(如上面动态图)
功能思路
第一步我们确认此时是勾选动作还是取消勾选动作
第二步我们确认此时勾选的数据是当前哪一个
第三步我们确认此时勾选类型的是客户还是店铺
第四步根据勾选动作和勾选类型去做不同的逻辑操作
1.此时是选中状态---此时是选中的是店铺,通过当前页的客户数据下的店铺数据循环跟我们当前选中的数据对比,找到当前选中的客户数据(leftParent),存在两种情况
- 此时店铺所挂载客户不存在右边,需将客户同时勾选上并往右边加上数据
- 此时店铺所挂载客户存在右边,只需将店铺数据往右边加
若是此时选中的是客户,存在两种情况
- 存在有店铺的情况, (勾选客户会自动勾选店铺 触发下面点击店铺的操作)
- 存在没有店铺 只有客户的情况 (重新写一种情况就是没有店铺,即当前点击的target.shopList没有值,或者为空数组)
2.此时是取消勾选状态--此时是选中的店铺,先通过当前页客户的数据下的店铺数据循环跟我们当前选中的数据对比,找到当前选中的客户数据(leftParent),并此时知道右边所有的数据循环跟当前选中的左边客户数据对比,找到此时右边跟左边的相同的数据(rightParent)
- 此时找到相同的数据rightParent下的shopList的长度大于0,找到当前店铺的下标,然后取消勾选
- 当rightParent的shopList的长度等于0时,说明此时的店铺数据全部取消勾选,此时要同时取消该客户的勾选
此时是取消勾选状态-此时选中的是客户,两种情况
- 点击的客户是没有店铺的情况(直接取消该客户)
- 点击的客户是存在店铺的情况(点击客户,触发点击事件把所有的店铺也取消勾选,走上面的店铺取消勾选事件)
数据结构
[{"custId": "460860740775766666","custCode": "ZT10009999","custName": "邵阳县永民雄新置业有限公司","labels": null,"labelnames": "智屏传统(剔除福州),乐华代理商","shopCodes": null,"shopList": [{"shopId": "460861654907518976","shopCode": "DP20230625366666","shopName": "智能家庭京东专卖店1号店","labels": null,"labelnames": null},{"shopId": "460864194063667200","shopCode": "DP202306258888888","shopName": "酷友天猫优品旗舰店1号店","labels": null,"labelnames": null},{"shopId": "460865727429906432","shopCode": "DP20230625188888","shopName": "酷友天猫优品旗舰店2号店","labels": null,"labelnames": null},{"shopId": "460888467817926656","shopCode": "DP20230625179999","shopName": "智能家庭京东专卖店2号店","labels": null,"labelnames": null}]},{"custId": "470195685059002368","custCode": "ZT10006888","custName": "邵阳县大山贸易有限公司","labels": null,"labelnames": null,"shopCodes": null,"shopList": null}
]
部分代码如下
<el-tableref="filterCusTable"v-loading="leftLoading":data="customerList":show-header="true"tooltip-effect="dark":header-cell-class-name="cellClass"default-expand-all:tree-props="{ children: 'shopList' }"row-key="custCode"max-height="600"min-height="400"@select="selectChange"@selection-change="handleSelectionChange"><el-table-column type="selection" width="30"></el-table-column><el-table-columnlabel="客户名称"prop="custName"></el-table-column><el-table-columnlabel="客户编码"prop="custCode"></el-table-column><el-table-columnlabel="客户标签"prop="labelnames"></el-table-column></el-table>/*** 用于树形表格多选,单选的封装* @param selection* @param row*/selectChange(selection, row) {console.log('selection', selection, row)const isCust = Array.isArray(row.shopList)//勾选的客户把以下的店铺全部带上勾选if (isCust) {const isAdd = !this.leftSelectedList.some((cust) => cust.custCode === row.custCode)console.log('isAdd', isAdd)// 这里得 nextTickthis.$nextTick(() => {row.shopList.forEach((shop) =>this.$refs.filterCusTable.toggleRowSelection(shop, isAdd))})}},//左侧客户选择handleSelectionChange(selections) {console.log('selections2', selections)if (this.initializing == true) return//selections是当前页勾选的数据 包含了客户和店铺//this.leftSelectedList 一开始进来页面此时左边已经勾选上的数据(切换分页的时候会跟着变化是当前页所勾选的数据)// 判断是新增还是减少let isAdd = false//当前选中的数据let target = null//选中的方法const toggleSelection = (row, selected) =>this.$refs.filterCusTable.toggleRowSelection(row, selected)console.log('selections2', selections)console.log('this.leftSelectedList', this.leftSelectedList)if (//可能会存在重复的数据selections.length > uniqBy(this.leftSelectedList, 'custCode').length) {isAdd = true//创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中target = difference(selections, this.leftSelectedList)[0]} else {// 取消选择target = difference(this.leftSelectedList, selections)[0]}this.leftSelectedList = selections//知道当前target点击的值是什么,就能区分我们当前勾选的是店铺还是客户//shopCode可能是null undefined和""const isShop = !!target.shopCode //此时就能知道点击的是店铺let parent = null//如果点击了店铺 通过当前页的数据循环找到当前满足一项的数据//就退出循环得到的数据就是父数据(客户)if (isShop) {parent = this.customerList.find((item) => {return (item.shopList || []).some((shop) => shop.shopCode === target.shopCode)})console.log('parent', parent)}//此时选中if (isAdd) {if (isShop) {//选中的是店铺,需要同时也选中父级的客户行toggleSelection(parent, true)this.pushToRight(target)} else {// 当前选中父亲,//1.存在有店铺的情况, (勾选客户会自动勾选店铺 触发下面点击店铺的操作)//2.存在没有店铺 只有客户的情况 (重新写一种情况就是没有店铺,即当前点击的target.shopList没有值,或者为空数组)toggleSelection(target, true)this.pushToRight(target)}}//取消选中else {if (isShop) {//如果点击的是店铺 则取消店铺操作勾选 从右边的数据移除this.removeRightShop(target)} else {//如果点击的是客户,还是两种情况//1.存在有店铺的情况, (勾选客户会自动勾选店铺 触发下面点击店铺的操作)//2.存在没有店铺 只有客户的情况 (重新写一种情况就是没有店铺,即当前点击的target.shopList没有值,或者为空数组)//2取消选中客户 没有店铺的情况this.removeRightShop(target)//1有店铺的情况,判断它此时shopList有数据,取消勾选 自动触发方法target.shopList &&target.shopList.length > 0 &&target.shopList.forEach((row) => toggleSelection(row, false))}}},//选中---把数据往右边List加pushToRight(row) {console.log('row', row)const leftParent = this.customerList.find((item) => {return (item.shopList || []).some((shop) => shop.shopCode === row.shopCode)})//leftParent可能会存在undefined的情况//判断右边的父级(客户)数据是否已经存在右边,并找到此时右边的父级(客户)数据const rightParent =leftParent &&this.rightCustomerList.find((item) => item.custCode === leftParent.custCode)if (rightParent) {// 如果右边已经存在该店铺的客户,// 但找不到该店铺的存在则直接push进来if (!(rightParent.shopList || []).some((shop) => shop.shopCode === row.shopCode)) {rightParent.shopList.push({ ...row })}} else {//如果右边不存在该店铺的客户if (leftParent) {const parent = { ...leftParent } //浅拷贝 方便进行数据处理和操作parent.shopList = [{ ...row }] //浅拷贝展开操作,生成一个新的对象,用新对象将parent.shopList数组对象替换this.rightCustomerList.push(parent) //通过以上的操作 这样就不会影响左边的数据// 刷新右边的数据this.tableData = this.rightCustomerList.slice((this.pageTwo - 1) * this.pagesize,this.pageTwo * this.pagesize)} else {//客户没有店铺的情况,直接添加//一定要记得深拷贝一份,否则会出现影响左边数据的存在(如取消勾选掉子的会splice干掉)if (!row.shopList || row.shopList.length == 0) {let pushRow = JSON.parse(JSON.stringify(row))this.rightCustomerList.push(pushRow)// 刷新右侧this.tableData = this.rightCustomerList.slice((this.pageTwo - 1) * this.pagesize,this.pageTwo * this.pagesize)}}}},//取消选中 --把数据从左边删除removeRightShop(row) {const leftParent = this.customerList.find((item) => {return (item.shopList || []).some((shop) => shop.shopCode === row.shopCode)})const rightParent =leftParent &&this.rightCustomerList.find((item) => item.custCode === leftParent.custCode)//此时知道右边的当前选中右边选中的数据,然后拿到当前选中的数据,//通过当前拿到rightParent数据中的shopList来判断//shopList长度大于0的是店铺--取消客户下的店铺//shopList长度为0的时候 说明所有店铺都取消,同时要取消该客户/* 1.此时找到相同的数据rightParent下的shopList的长度大于0,找到当前店铺的下标,然后取消勾选2.当rightParent的shopList的长度等于0时,说明此时的店铺数据全部取消勾选,此时要同时取消该客户的勾选 */if (rightParent) {//客户有店铺的情况console.log('执行了几次', rightParent)const shopIndex = rightParent.shopList.findIndex((shop) => shop.shopCode === row.shopCode)//获取到当前删除店铺的下标 然后取消勾选if (shopIndex > -1) {rightParent.shopList.splice(shopIndex, 1)}if (rightParent.shopList.length === 0) {const custIndex = this.rightCustomerList.findIndex((item) => item.custCode === rightParent.custCode)if (custIndex > -1) {this.rightCustomerList.splice(custIndex, 1)// 刷新右侧this.tableData = this.rightCustomerList.slice((this.pageTwo - 1) * this.pagesize,this.pageTwo * this.pagesize)// 左侧取消选中父级this.$refs.filterCusTable.toggleRowSelection(leftParent, false)}}} else {//客户没有店铺的情况console.log('row', row)if (!row.shopList || row.shopList.length == 0) {const custIndex = this.rightCustomerList.findIndex((item) => item.custCode === row.custCode)console.log('custIndex', custIndex)if (custIndex > -1) {this.rightCustomerList.splice(custIndex, 1)// 刷新右侧this.tableData = this.rightCustomerList.slice((this.pageTwo - 1) * this.pagesize,this.pageTwo * this.pagesize)}}}},
相关文章:
element-ui树形表格,左边勾选,右边显示选中的数据-功能(如动图)
功能如图 功能需求 表格树形表格勾选数据,右边显示对应勾选的数据内容,选中客户,自动勾选所有的店铺(子级),选中其中一个店铺,自动勾选上客户(父级),同时会存在只有客户(下面没有子级的情况&am…...
Android数字价格变化的动画效果的简单实现
原理:使用ValueAnimator属性动画类实现,它通过值的改变手动设置对象的属性值来实现动画效果。直接贴代码: public static void doNumberAnim(TextView tvPrice, float startNumber, float endNumber) {ValueAnimator animator ValueAnimato…...
Win10无法投影关闭3D模式
Win10不小心开启了3D模式,插上投影仪就一闪一闪的,无法正投影 解决办法: 1. 打开注册表工具regedit,删除以下注册表,重启电脑 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configurat…...
FFmpeg 编码详细流程
介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。FFmpeg 本身不具有音视频编码的功能和底层能力,只是对各类第三方的编码器API 进行封装调用。老版本的 FFmpeg 将avcodec_encode_video2()作为视频的解码函数 API,将avcodec_encode_audio2(…...
05如何做微服务架构设计
一句话导读 微服务架构设计方法有:领域驱动设计DDD(Domain-Driven-Design)、12因素应用(12-Factor App)、事件驱动架构EDA(Event-Driven Architecture)等等,但是他们都必须遵守微服务…...
安卓开发问题记录:需要常量表达式
问题原因 写代码过程中爆出这个错误:需要常量表达式,定位到switch。 解决方法:把switch case,改成if else 错误源代码: public void onClick(View view) {switch (view.getId()) {case R.id.iv_code:RxCaptcha.build(…...
回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测
回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测预测效果基本介绍研究内容程序设计参考资料…...
配置root账户ssh免密登录并使用docker-machine构建docker服务
简介 Docker Machine是一种可以在多种平台上快速安装和维护docker运行环境,并支持多种平台,让用户可以在很短时间内在本地或云环境中搭建一套docker主机集群的工具。 使用docker-machine命令,可以启动、审查、停止、重启托管的docker 也可以…...
【力扣周赛】第357场周赛
【力扣周赛】第357场周赛 2810. 故障键盘题目描述解题思路 2811. 判断是否能拆分数组题目描述解题思路 2810. 故障键盘 题目描述 描述:你的笔记本键盘存在故障,每当你在上面输入字符 ‘i’ 时,它会反转你所写的字符串。而输入其他字符则可以…...
多线程案例(4)-线程池
文章目录 多线程案例四四、线程池 大家好,我是晓星航。今天为大家带来的是 多线程案例-线程池 相关的讲解!😀 多线程案例四 四、线程池 线程池是什么 虽然创建线程 / 销毁线程 的开销 想象这么一个场景: 在学校附近新开了一家…...
【数据结构OJ题】轮转数组
原题链接:https://leetcode.cn/problems/rotate-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 1. 方法一:暴力求解,将数组的第一个元素用临时变量tmp存起来,再将数组其他元素往右挪动一步&…...
现代C++中的从头开始深度学习:【4/8】梯度下降
一、说明 在本系列中,我们将学习如何仅使用普通和现代C编写必须知道的深度学习算法,例如卷积、反向传播、激活函数、优化器、深度神经网络等。 在这个故事中,我们将通过引入梯度下降算法来介绍数据中 2D 卷积核的拟合。我们将使用卷积和上一个…...
Yolov5缺陷检测/目标检测 Jetson nx部署Triton server
使用AI目标检测进行缺陷检测时,部署到Jetson上即小巧算力还高,将训练好的模型转为tensorRT再部署到Jetson 上供http或GRPC调用。1 Jetson nx 刷机 找个ubuntu 系统NVIDIA官网下载安装Jetson 的sdkmanager一步步刷机即可。 本文刷的是JetPack 5.1, 其中包…...
MobaXterm 中文乱码, 及pojie
中文解决方法: 把“连字”去掉! MobaXterm网页,可以生成一个授权文件Custom.mxtpro。放在安装目录就可以了 MobaXterm Keygen (husbin.top)http://b70.husbin.top:5000/...
java: 程序包sun.misc不存在
启动失败,rebuild时也报错:java: 程序包sun.misc不存在 问题出在JDK版本上,这个包在JDK9的时候已经被弃用了,这里改回JDK8即可 步骤如下:...
WSL2Linux 子系统(五)
WLS2Linux 子系统编译 Android 上一篇文章中讲解 《WLS2Linux 子系统迁移/恢复》,从C盘迁移到D盘。既可以防止C盘爆红,又可以释放磁盘空间。有更大存储空间意味大有可为,比如说编译Android系统。本文则以开源 firefly Android10代码为例简单…...
java 企业工程管理系统软件源码 自主研发 工程行业适用 em
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...
IPO观察丨困于门店扩张的KK集团,还能讲好增长故事吗?
KK集团发起了其IPO之路上的第三次冲击。 近日,KK集团更新了招股书,继续推进港交所上市进程,此前两次上市搁置后终于有了新动向。从更新内容来看,KK集团招股书披露了公司截至2023年一季度的最新业绩,交出一份不错的“成…...
【iOS】RunLoop
前言-什么是RunLoop? 什么是RunLoop? 跑圈?字面上理解确实是这样的。 Apple官方文档这样解释RunLoop RunLoop是与线程息息相关的基本结构的一部分。RunLoop是一个调度任务和处理任务的事件循环。RunLoop的目的是为了在有工作的时候让线程忙起来&#…...
数据包传输方式:单播、多播、广播、组播、泛播
数据包传输方式 单播、多播、广播、组播、泛播 网络中假设X代表所有的机器,Y代表X中的一部分机器,Z代表一组机器,1代表一台机器,那么 1:1 那就是单播;1:Y 那就是多播;1࿱…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
