JS antdv实现表格树形级联效果

news2025/1/12 21:55:30

概述

项目中需实现以下这种效果:级联数据,表格横向排列,数据之间相互联动。现有UI组件无法满足此需求,只能撸起袖子加油干!!
在这里插入图片描述
实现效果如下
请添加图片描述
开发前先准备一个树形数据 treeData.js

const treeData = [
  {
    areaName: "江苏",
    areaCode: "100",
    checked: false,
    indeterminate: false,
    order: 1,
    children: [
      {
        areaName: "无锡",
        areaCode: "1001",
        parentCode: "100",
        checked: false,
        indeterminate: false,
        order: 1,
        children: [
          {
            areaName: "鼓楼区",
            areaCode: "10011",
            parentCode: "1001",
            checked: false,
            indeterminate: false,
            order: 1,
            children: [],
          },
          {
            areaName: "玄武区",
            areaCode: "10012",
            parentCode: "1001",
            checked: false,
            indeterminate: false,
            order: 2,
            children: [],
          },
          {
            areaName: "秦港区",
            areaCode: "10013",
            parentCode: "1001",
            checked: false,
            indeterminate: false,
            order: 3,
            children: [],
          },
          {
            areaName: "浦口区",
            areaCode: "10014",
            parentCode: "1001",
            checked: false,
            indeterminate: false,
            order: 4,
            children: [],
          },
        ],
      },
      {
        areaName: "南京",
        areaCode: "1002",
        parentCode: "100",
        checked: false,
        indeterminate: false,
        order: 1,
        children: [
          {
            areaName: "鼓楼区2",
            areaCode: "10021",
            parentCode: "1002",
            checked: false,
            indeterminate: false,
            order: 1,
            children: [],
          },
          {
            areaName: "玄武区2",
            areaCode: "10022",
            parentCode: "1002",
            checked: false,
            indeterminate: false,
            order: 2,
            children: [],
          },
          {
            areaName: "秦港区2",
            areaCode: "10023",
            parentCode: "1002",
            checked: false,
            indeterminate: false,
            order: 3,
            children: [],
          },
          {
            areaName: "浦口区2",
            areaCode: "10024",
            parentCode: "1002",
            checked: false,
            indeterminate: false,
            order: 4,
            children: [],
          },
        ],
      },
    ],
  },
  {
    areaName: "浙江",
    areaCode: "200",
    checked: false,
    indeterminate: false,
    order: 1,
    children: [
      {
        areaName: "杭州",
        areaCode: "2001",
        parentCode: "200",
        checked: false,
        indeterminate: false,
        order: 1,
        children: [
          {
            areaName: "鼓楼区1",
            areaCode: "20011",
            parentCode: "2001",
            checked: false,
            indeterminate: false,
            order: 1,
            children: [],
          },
          {
            areaName: "玄武区1",
            areaCode: "20012",
            parentCode: "2001",
            checked: false,
            indeterminate: false,
            order: 2,
            children: [],
          },
          {
            areaName: "秦港区1",
            areaCode: "20013",
            parentCode: "2001",
            checked: false,
            indeterminate: false,
            order: 3,
            children: [],
          },
          {
            areaName: "浦口区1",
            areaCode: "20014",
            parentCode: "2001",
            checked: false,
            indeterminate: false,
            order: 4,
            children: [],
          },
        ],
      },
      {
        areaName: "宁波",
        areaCode: "2002",
        parentCode: "200",
        checked: false,
        indeterminate: false,
        order: 1,
        children: [
          {
            areaName: "鼓楼区2",
            areaCode: "20021",
            parentCode: "2002",
            checked: false,
            indeterminate: false,
            order: 1,
            children: [],
          },
          {
            areaName: "玄武区2",
            areaCode: "20022",
            parentCode: "2002",
            checked: false,
            indeterminate: false,
            order: 2,
            children: [],
          },
          {
            areaName: "秦港区2",
            areaCode: "20023",
            parentCode: "2002",
            checked: false,
            indeterminate: false,
            order: 3,
            children: [],
          },
          {
            areaName: "浦口区2",
            areaCode: "20024",
            parentCode: "2002",
            checked: false,
            indeterminate: false,
            order: 4,
            children: [],
          },
        ],
      },
    ],
  },
];
export default treeData;

完整代码
具体的每一个细节我都在代码注释了,这里就不单独抽出来赘述了,详细的分析请看大屏幕…

<template>
  <a-modal
    :title="addConfig.title"
    :showSubmit="false"
    :visible="addConfig.visible"
    @ok="handleAddOk"
    @cancel="handleCancel"
  >
    <div class="container_box">
      <div class="container_header">
        <div v-for="item in 3" :key="item" class="header_item">
          <div class="title"><span>名称</span></div>
          <div class="title"><span>排序</span></div>
        </div>
      </div>
      <div class="container_body">
        <div class="body_item" v-for="(list, index) in listData" :key="index">
          <div
            class="item_list"
            :style="{
              backgroundColor: item.clickStatus
                ? 'rgba(19,194,194,.3)'
                : '#ffffff',
            }"
            v-for="item in list"
            :key="item.areaCode"
            @click.capture="handleClickAreaItem(item)"
          >
            <div class="item">
              <a-checkbox
                :indeterminate="item.indeterminate"
                v-model="item.checked"
                @change="onCheckAllChange($event, item)"
              >
                {{ item.areaName }}
              </a-checkbox>
            </div>
            <div class="item">
              <a-input v-model="item.order" placeholder="排序" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </a-modal>
</template>

<script>
import treeData from "./treeData";
let filterData = [];
export default {
  name: "addArea",
  props: {
    addConfig: Object,
  },
  data() {
    return {
      listData: [],
    };
  },
  mounted() {
    this.handleTreeData(treeData, 1);
    // 初始化数据
    treeData[0].clickStatus = true;
    treeData[0].children[0].clickStatus = true;
    this.listData = [
      treeData,
      treeData[0].children,
      treeData[0].children[0].children,
    ];
  },
  methods: {
    // 点击每一个item 显示选中状态并进行数据联动
    handleClickAreaItem(item) {
      if (item.level === 3) return;
      let list = [];
      if (item.parentCode) {
        // 点击第二或第三级
        this.handleFilterData(treeData, item.parentCode);
        list = filterData[0]?.children;
      } else {
        // 点击第一级
        list = treeData;
        // 切换第一级时 第二级默认选择第一个
        let arr = treeData.filter((lis) => lis.areaCode === item.areaCode);
        arr[0]?.children.forEach((lis, index) => {
          if (index === 0) {
            lis.clickStatus = true;
          } else {
            lis.clickStatus = false;
          }
        });
      }
      list.forEach((lis) => {
        if (lis.areaCode === item.areaCode) {
          lis.clickStatus = true;
          // 子级数据跟随联动
          if (item.level === 1) {
            this.listData[1] = lis.children;
            this.listData[2] = lis.children[0].children;
          } else if (item.level === 2) {
            this.listData[2] = lis.children;
          }
        } else {
          lis.clickStatus = false;
        }
      });
    },
    handleTreeData(list, levelIndex) {
      list.forEach((lis) => {
        lis.clickStatus = false;
        // 动态标记每层层级
        lis.level = levelIndex;
        if (lis.children && lis.children.length !== 0)
          this.handleTreeData(lis.children, levelIndex + 1);
      });
    },
    handleAddOk(e) {
      e && e.preventDefault();
    },
    handleCancel() {
      this.$emit("cancel");
    },
    // 向下处理树形选中/未选中
    handleDownTreeCheck(arr, checked) {
      arr.forEach((iii) => {
        iii.indeterminate = false;
        iii.checked = checked;
        if (iii.children && iii.children.length !== 0)
          this.handleDownTreeCheck(iii.children, checked);
      });
    },
    // 向上处理树形选中/未选中
    handleUpTreeCheck(item) {
      this.handleFilterData(treeData, item.parentCode);
      let list = filterData[0];
      let status1 = list.children.some((ii) => ii.checked);
      let status2 = list.children.every((ii) => ii.checked);
      let statusIn = list.children.some((ii) => ii.indeterminate);
      // 当不全选中且子集有勾选中 或者 子集有indeterminate状态为true
      list.indeterminate = status1 || statusIn;
      // 当全选中的时候 indeterminate 状态 为false
      if (status2) list.indeterminate = false;
      list.checked = status2;
      // 层层向上处理
      if (list.parentCode) this.handleUpTreeCheck(list);
    },
    onCheckAllChange(e, item) {
      item.indeterminate = false;
      filterData = [];
      // 当前点击的该项中有父级的情况下 比如当前点击项为第二、三....
      if (item.parentCode) this.handleFilterData(treeData, item.parentCode);
      // 当前点击的该项中存在父级数据情况下 比如当前点击项为第二、三.... 则向上处理元素状态
      if (filterData.length > 0) this.handleUpTreeCheck(item);
      // 当前点击的该项中存在子集数据情况下 则向下处理元素状态
      if (item.children && item.children.length > 0)
        this.handleDownTreeCheck(item.children, e.target.checked);
    },
    handleFilterData(list, parentCode) {
      // 过滤数据
      list.forEach((lis) => {
        if (lis.areaCode === parentCode) {
          filterData = [];
          filterData.push(lis);
        }
        if (lis.children && lis.children.length !== 0)
          this.handleFilterData(lis.children, parentCode);
      });
    },
  },
};
</script>

<style lang="less" scoped>
/deep/.ant-modal {
  width: 840px !important;
  .ant-modal-close {
    color: #fff;
    .ant-modal-close-x {
      height: 47px;
      line-height: 47px;
    }
  }
  .ant-modal-header {
    padding: 12px 20px;
    background-color: #02c7b5;
    .ant-modal-title {
      font-size: 16px;
      font-weight: 500;
      color: #ffffff;
    }
  }
  .ant-modal-body {
    // padding: 24px 27px 6px;
  }
  .container_box {
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    .container_header {
      display: flex;
      align-items: center;
      width: 100%;
      background-color: #f4f7fb !important;
      border-radius: 6px 6px 0px 0px;
      .header_item {
        flex: 4;
        height: 42px;
        line-height: 42px;
        display: flex;
        align-items: center;
        .title {
          flex: 6;
          text-align: center;
          font-size: 14px;
          font-weight: 400;
          color: #242525;
        }
      }
    }
    .container_body {
      display: flex;
      width: 100%;
      .body_item {
        flex: 4;
        flex-direction: column;
        .item_list {
          display: flex;
          align-items: center;
          margin-top: 10px;
          .item {
            flex: 6;
            text-align: center;
            font-size: 14px;
            font-weight: 400;
            color: #242525;
            .ant-input {
              width: 86px !important;
            }
          }
        }
        &:nth-child(2) {
          border-left: 2px solid #f1f1f1;
          border-right: 2px solid #f1f1f1;
        }
      }
    }
  }
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux常用命令【多图预警】

Linux常用命令 文章目录 Linux常用命令Linux虚拟机的安装Linux系统目录结构Linux命令的语法基础命令查看当前目录下所有子目录和子文件ls查看命令手册man查看当前目录pwd切换到指定目录cd 管道符 |文件目录操作命令创建一级目录&#xff08;文件夹&#xff09;mkdir创建多级目录…

计算机毕业论文内容参考|基于微信小程序的学生课表系统的设计与实现

文章目录 导文摘要前言绪论1课题背景2国内外现状与趋势3课题内容相关技术与方法介绍系统分析系统设计系统实现系统测试总结与展望1本文总结2后续工作展望导文 计算机毕业论文内容参考|基于微信小程序的学生课表系统的设计与实现 摘要 基于微信小程序的学生课表系统是一个方便学…

【电路原理学习笔记】第2章:电压、电流和电阻:2.8 电气安全

第2章&#xff1a;电压、电流和电阻 2.8 电气安全 2.8.1 触电 电流&#xff08;而非电压&#xff09;通过人的身体是触电的的原因。当然&#xff0c;需要有电压施加在有电阻的物体上才能产生电流。当人身体上的一个点与电压接触&#xff0c;而另一个点与不同的电压或地面接触…

玄子Share - mybatis-Plus 3.5.3.1 学习笔记

玄子Share - mybatis-Plus 3.5.3.1 学习笔记 介绍 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 [MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 愿景&#xff1a;…

docker 镜像的使用与创建(三)

相关文章&#xff1a; linux上docker容器运行web应用简单介绍(二&#xff09;_做测试的喵酱的博客-CSDN博客 linux docker安装及报错处理_做测试的喵酱的博客-CSDN博客 Docker 容器使用 | 菜鸟教程 linux应用docker基本使用&#xff08;一&#xff09;_做测试的喵酱的博客-…

29. 求出商品连续售卖的时间区间

文章目录 题目需求思路一实现一题目来源 题目需求 从订单详情表&#xff08;order_detail&#xff09;中&#xff0c;求出商品连续售卖的时间区间。 期望结果如下&#xff1a; sku_id &#xff08;商品id&#xff09;start_date &#xff08;起始时间&#xff09;end_date &…

鸢尾花书简介

鸢尾花书简介 鸢尾花书 系列介绍1《编程不难》2《可视之美》3《数学要素》4《矩阵力量》5《统计至简》6《数据有道》7《机器学习》 重要链接 特别棒&#xff0c;极力推荐&#xff01;&#xff01;&#xff01; 鸢尾花书 系列介绍 1《编程不难》 《编程不难》&#xff1a;https:…

win11预览版更新,并尝试使用Copilot

文章目录 win11预览版更新&#xff0c;并使用Copilot先说结果所需内容具体操作更新操作系统版本更新Edge安装ViVeTool v0.3.3 测试Copilot问题唯一优点 总结 win11预览版更新&#xff0c;并使用Copilot 先说结果 体验一言难尽&#xff0c;就相当于是一个快捷聊天提问窗口。 自…

C语言实现WiFi数据收发(电脑作为服务器)

功能实现&#xff1a; 手机与电脑在一个局域网&#xff0c;实现手机与电脑之间数据收发。 主要是用socket协议完成功能。 电脑作为服务器&#xff0c;手机作为客户端 编程环境&#xff1a; 电脑端变成环境&#xff1a;VC6.0 手机端WiFi助手&#xff1a; 核心代码&#xff1a; …

K8S平台应用安全(Secret Service Ingress)

平台应用安全 1 平台应用安全1.1 敏感数据1.1.1 应用数据1.1.2 Secret基础1.1.3 Secret案例11.1.4 Secret案例2 1.2 数据访问1.2.1 网络体系解读1.2.2 Service实践1.2.3 Service进阶1.2.4 Service解读 1.3 应用流量1.3.1 Ingress基础1.3.2 Ingress实践1.3.3 Ingress进阶1.3.4 I…

用Python实现黑客代码

前言 用Python实现黑客代码&#xff0c;根本关不掉的窗口 &#x1f4dd;个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列&#xff1a; ☄️爬虫JS逆向系列专栏 - 爬虫逆向教学 ☄️python系列专栏 - 从零开始学python 首先先介绍一下使用到的tkinter库 Tkinter 是 P…

通付盾联合嘶吼安全产业研究院共同发布《数据安全细分市场调研报告》并成功入选数据安全产业图谱多项细分领域,附报告!

7月4日&#xff0c;通付盾联合嘶吼安全产业研究院共同发布《时维鹰扬履践致远&#xff1a;数据安全细分市场调研报告2023》。 百炼露锋芒&#xff0c;本次《时维鹰扬履践致远&#xff1a;数据安全细分市场调研报告2023》聚焦数据安全市场细分领域市场规模、厂商玩法和产品竞争情…

二十三种设计模式第十四篇--策略模式

策略模式&#xff1a;主要围绕一个类的行为或者其算法在运行时更改&#xff0c;也是一种行为型模式。 在软件开发中&#xff0c;我们经常遇到需要根据不同的情况选择不同算法或行为的情况。传统的做法是使用大量的条件语句来实现这种逻辑&#xff0c;但这样的实现方式往往难以…

Numpy学习(参考)

目录 一、前言 二、numpy官方文档 文档划分 参数规范 相关知识明知 Routines学习(部分) 1、创建 2、数组操作常用 ufunc 三、numpy基本操作 开篇探索 数据类型 创建数组 创建数组有5种常规机制 常用创建方法 拷贝创建 数组运算 形状操作 查看形状 形状变换 …

第124天:内网安全-代理技术Socks协议路由不出网后渗透通讯CS-MSF上线

知识点 #知识点&#xff1a; 1、代理软件使用-Win&Linux 2、代理协议使用-Socks4/5 3、CS&MSF-网络通讯&控制上线-隧道技术&#xff1a;解决不出网协议上线的问题&#xff08;利用出网协议进行封装出网&#xff09; -代理技术&#xff1a;解决网络通讯不通的问题&…

MySQL数据库------------数据库的安装-----开始步入梦想

作者前言 欢迎小可爱们前来借鉴我的gtiee秦老大大 (qin-laoda) - Gitee.com —————————————————————————————————— 这一篇文章主要讲解一下MySQL的下载 数据库MySQL 这是 CentOS7 的 mysql 安装&#xff0c;如果有其他版本的需求&#xff…

C++ 环境设置

本地环境设置 如果您想要设置 C 语言环境&#xff0c;您需要确保电脑上有以下两款可用的软件&#xff0c;文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、OS Edit command、Brief、Epsilon、EMACS 和 vim/vi。 文本编辑器的名…

tqdm笔记

目录 tqdm笔记导入显示进度条与enumerate一起使用 tqdm报错tqdm在notebook里每次刷新增加一行 tqdm笔记 导入 from tqdm import tqdm显示进度条 for i in tqdm(range(100)):time.sleep(0.01)与enumerate一起使用 a list(range(100)) for i, j in enumerate(tqdm(a)):time.…

Windows系统封装教程

一、封装前准备工作 虚拟机软件&#xff1a;VMware Workstation Pro windows镜像&#xff1a;windows 10.iso PE镜像&#xff1a;微PE.iso &#xff08;微PE工具箱&#xff09; 工具包&#xff1a;软媒魔方 封装工具&#xff1a;sysceo&#xff08;SC封装工具3.0&#xff…

java模拟面试题1

1、哪些问题是HTTPS无法解决的&#xff1f; Http是基于TCP协议的&#xff0c;在网络层的传输耗时比较长&#xff0c;https没有解决这个问题&#xff1b;http头是不能压缩的&#xff0c;每次要传递很大的数据包&#xff0c;每个连接也只能支持一个请求。同时https应用了很多加密…