当前位置: 首页 > news >正文

【前后端的那些事】treeSelect树形结构数据展示

文章目录

    • tree-selector
      • 1. 新增表单组件
      • 2. 在父组件中引用
      • 3. 父组件添加新增按钮
      • 4. 树形组件
        • 4.1 前端代码
        • 4.2 后端代码

前言:最近写项目,发现了一些很有意思的功能,想写文章,录视频把这些内容记录下。但这些功能太零碎,如果为每个功能都单独搭建一个项目,这明显不合适。于是我想,就搭建一个项目,把那些我想将的小功能全部整合到一起。实现 搭一次环境,处处使用。

本文主要实现一下两个功能

  1. 新增表单, 更新表单组件编写
  2. treeSelect树形结构编写

环境搭建
文章链接

已录制视频
视频链接

tree-selector

这个功能是table-tree功能的附属产品。是为了能在新增表单中,更方便选择上级节点所开发的功能。因此,我们得先把新增表单组件开发出来

新增、修改逻辑
在这里插入图片描述

tree形组件

在这里插入图片描述

1. 新增表单组件

/src/views/welcome/treeAddOrUpdate.vue

<script setup lang="ts">
import { UnitEntity } from "@/api/tree";
import { ref, reactive } from "vue";
const dialogVisible = ref(false);let form = reactive(new UnitEntity());
const title = ref("新增表单");// 定义init方法, 让父组件调用
const init = data => {console.log(data);if (data) {form = data;title.value = "编辑表单";} else {title.value = "新增表单";}dialogVisible.value = true;
};// 暴露方法
defineExpose({ init });// 提交表单
const submit = () => {console.log(form);
};
</script><template><el-dialog v-model="dialogVisible" :title="title"><el-form :model="form"><el-form-item label="单元"><el-input v-model="form.unit" /></el-form-item><el-form-item label="父id"><el-input v-model="form.pid" /></el-form-item></el-form><el-button @click="submit">提交</el-button></el-dialog>
</template><style lang="scss" scoped></style>

2. 在父组件中引用

/src/views/welcome/index.vue

<script setup lang="ts">
import { ref, onMounted, nextTick } from "vue";
import TreeAddOrUpdate from "./treeAddOrUpdate.vue";const dialogVisible = ref(false);// 引用子组件
const treeAddOrUpdateRef = ref();// ...
</script><template><!--ref引用组件--><tree-add-or-update v-if="dialogVisible" ref="treeAddOrUpdateRef" />
</template>

3. 父组件添加新增按钮

/src/views/welcome/index.vue

<script setup lang="ts">
// 新增/修改 都可以使用该方法
const addOrUpdate = data => {console.log(data);dialogVisible.value = true;// nextTick保证treeAddOrUpdateRef能够引用到子组件nextTick(() => {// 调用子组件暴露的init方法, 设置数据treeAddOrUpdateRef.value.init(data);});
};
</script><template><el-button type="primary" @click="addOrUpdate">新增</el-button>
</template>

完成以上步骤,我们就可以点击新增表单,但这个界面对于用户来说其实并不美好。谁知道父id是什么?因此我们采用tree-select的形式来提高界面的可使用性

4. 树形组件

在这里插入图片描述

我们使用的是element plus的TreeSelect组件,具体文档如下:[TreeSelect 树形选择 | Element Plus (element-plus.org)]()

4.1 前端代码
  • /src/api/tree.ts
export class LabelVo {
id: Number;
label: String;
value: String;
children: Array<LabelVo>;
}/** 获取全部的treeLabel */
export const getLabelTree = () => {
return http.request<R<Array<LabelVo>>>("get",baseUrlApi("unit/listTreeSelect")
);
};/** 根据id查询节点 */
export const getNodeById = (id: Number) => {
return http.request<R<LabelVo>>("get", baseUrlApi(`unit/listNode?id=${id}`));
};
  • /src/views/welcome/treeAddOrUpdate.vue
<template>
<el-tree-selectv-model="value":data="data"check-strictlyshow-checkbox@check-change="handleCheckChange"style="width: 240px"/>
</template><script>
// 定义init方法, 让父组件调用
const init = data => {console.log(data);if (data) {form = data;title.value = "编辑表单";// 查询上级节点数据(根据id返回{value, label, id})getNodeById(form.pid).then(res => {if (res.code === 0) {value.value = res.data.value;}});} else {title.value = "新增表单";}console.log(form);dialogVisible.value = true;
};const value = ref();
const data = ref<Array<LabelVo>>();const handleCheckChange = (data: LabelVo, checked, indeterminate) => {console.log(data);console.log(checked);if (checked) {form.pid = data.id;}
};
</script>

tip: init方法改动

4.2 后端代码
  • 定义实体类
package com.fgbg.demo.vo;import lombok.Data;import java.util.List;@Data
public class LabelVo {private String label;private String value;private Integer id;private Integer pid;private List<LabelVo> children;
}
  • 返回tree-selector展示所需数据

        @RequestMapping("/listTreeSelect")public R listTreeSelect() {List<TbUnit> tbUnitList = unitService.list();List<LabelVo> list = tbUnitList.stream().map(e -> {LabelVo vo = new LabelVo();vo.setValue(e.getUnit());vo.setLabel(e.getUnit());vo.setId(e.getId());vo.setPid(e.getPid());return vo;}).collect(Collectors.toList());// TbUnit -> LabelVo// 建立map映射(id->index)HashMap<Integer, Integer> map = new HashMap<>();for (int index = 0; index < list.size(); index++) {Integer id = list.get(index).getId();map.put(id, index);}// ...for (int i = 0; i < list.size(); i++) {LabelVo node = list.get(i);Integer pid = node.getPid();// 有父亲if (pid != null) {// 找到pid的父亲, 并把当前节点(node)添加到父亲节点的children里面Integer indexParent = map.get(pid);// 获取父亲节点LabelVo parent = list.get(indexParent);if (parent.getChildren() == null) {parent.setChildren(new ArrayList<>());}// 向父亲节点的children字段添加当前nodeparent.getChildren().add(node);}}// 过滤出一级节点List<LabelVo> ans = list.stream().filter(e -> e.getPid() == null).collect(Collectors.toList());return R.ok().put("data", ans);}
  • 根据id查询数据

        // 根据id查询节点数据{value id label}@RequestMapping("/listNode")public R listNode(@RequestParam Integer id) {TbUnit unit = unitService.getById(id);LabelVo labelVo = new LabelVo();labelVo.setLabel(unit.getUnit());labelVo.setValue(unit.getUnit());labelVo.setId(unit.getId());return R.ok().put("data", labelVo);}
    

相关文章:

【前后端的那些事】treeSelect树形结构数据展示

文章目录 tree-selector1. 新增表单组件2. 在父组件中引用3. 父组件添加新增按钮4. 树形组件4.1 前端代码4.2 后端代码 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&#xff0c;想写文章&#xff0c;录视频把这些内容记录下。但这些功能太零碎&#xff0c…...

华为OD机试 - 最长子字符串的长度(二)(Java JS Python C)

题目描述 给你一个字符串 s,字符串 s 首尾相连成一个环形,请你在环中找出 l、o、x 字符都恰好出现了偶数次最长子字符串的长度。 输入描述 输入是一串小写的字母组成的字符串 输出描述 输出是一个整数 备注 1 ≤ s.length ≤ 5 * 10^5s 只包含小写英文字母用例 输入alolob…...

【VRTK】【Unity】【游戏开发】更多技巧

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 本篇将较为零散但常用的VRTK开发技巧集合在一起,主要内容: 创建物理手震动反馈高亮互动对象【创建物理手】 非物理手状态下,你的手会直接…...

Spark 读excel报错,scala.MatchError

Spark3详细报错: scala.MatchError: Map(treatemptyvaluesasnulls -> true, location -> viewfs://path.xlsx, inferschema -> false, addcolorcolumns -> true, header -> true) (of class org.apache.spark.sql.catalyst.util.CaseInsensitiveMap)scala代码…...

【漏洞复现】Office365-Indexs-任意文件读取

漏洞描述 Office 365 Indexs接口存在一个任意文件读取漏洞,攻击者可以通过构造精心设计的请求,成功利用漏洞读取服务器上的任意文件,包括敏感系统文件和应用程序配置文件等。通过利用此漏洞,攻击者可能获得系统内的敏感信息,导致潜在的信息泄露风险 免责声明 技术文章…...

使用Python向RabbitMQ发送JSON数据只需要一个send_json方法

发送JSON数据 通过调用rabbitmq.send_json(channel, user, queueresult)能够更简单的实现发送JSON数据。 生产者 import json import rabbitmq# 建立连接 connection rabbitmq.get_connection()# 创建管道 channel connection.channel()# 创建队列 queue_name "user…...

Gitlab Gitee GitHub 远程仓库显示图片

大家好我是苏麟 , 今天出一期开发之外的如何在远程仓库展示图片 . 以GitLab为例 1.首先我们要把一张图片上传到远程仓库 . 2.第二步,点击图片 3.鼠标右键点击下载左键点击复制连接 4.找到我们要上传的md文件 , 把连接复制到 ( ) 里 , 这样上传md之后就可以看到图片了 . 这期就到…...

JS常用的几种事件

JavaScript常用的几种事件有&#xff1a; 点击事件&#xff1a;当用户点击某个元素时触发&#xff0c;常用于按钮、链接等交互元素。事件名称为"click"。 javascriptbutton.addEventListener(click, function() { alert(按钮被点击了&#xff01;); }); 鼠标移动事…...

代码随想录算法训练营第一天| 27 移除元素 704 二分查找

目录 27 移除元素 704 二分查找 27 移除元素 快指针遍历&#xff0c;慢指针记录 class Solution { public:int removeElement(vector<int>& nums, int val) {int l 0,r 0;for(;r < nums.size();r){if(nums[r] val){}else{nums[l] nums[r];}}return l;} }; …...

深度生成模型(Deep Generative Models)

什么是机器学习 深度生成模型&#xff08;Deep Generative Models&#xff09;是一类利用深度学习方法生成新样本的模型。这些模型通常被用于生成与训练数据集相似的新数据&#xff0c;例如图像、文本或音频。深度生成模型的两个主要类型是生成对抗网络&#xff08;GANs&#…...

C++(20):vector通过erase,erase_if删除符合条件的元素

C++20前,vector可以通过成员函数erase删除迭代器指定的元素,并返回被删除的下一个元素: iterator erase( iterator pos ); iterator erase( iterator first, iterator last ); 1.删除单个元素 #include <vector> #include <iostream> #include <algorithm&…...

树莓派ubuntu:新增用户

切换到Root用户 sudo -i创建新用户 useradd -m 新用户名设置密码 passwd 新用户名将新用户加入sudo用户组 adduser newname sudo拷贝数据 cp -R /home/旧用户名/* /home/新用户名/查看用户所属组 id 新用户名更改文件所属 sudo chown 新用户名:group /home/新用户名/*gr…...

C //练习 5-14 修改排序程序,使它能处理-r标记。该标记表明,以逆序(递减)方式排序。要保证-r和-n能够组合在一起使用。

C程序设计语言 &#xff08;第二版&#xff09; 练习 5-14 练习 5-14 修改排序程序&#xff0c;使它能处理-r标记。该标记表明&#xff0c;以逆序&#xff08;递减&#xff09;方式排序。要保证-r和-n能够组合在一起使用。 注意&#xff1a;代码在win32控制台运行&#xff0c…...

CAN总线报文格式———标准数据帧

标准数据帧 : 用于节点向外传送数据 标准数据帧由帧起始、仲裁段、控制段、数据段、CRC段、ACK段、帧结束等组成。 一、总线空闲&#xff08;Bus Idle&#xff09; CAN总线空闲时&#xff0c;总线上会输出持续的高电平“1”。当总线空闲时任何连接的单元都可以开始发送新的报…...

DFT中的SCAN、BIST、ATPG基本概念

DFT中的SCAN、BIST、ATPG基本概念 SCAN 定义 扫描路径法是一种针对时序电路芯片的DFT方案&#xff0c;目标是在不影响正常功能的情况下来能够提高可控性和可观测性。 原理 原理是将时序电路可以模型化为一个组合电路网络和带触发器(Flip-Flop&#xff0c;简称FF)的时序电路…...

掌握 Vue 响应式系统,让数据驱动视图(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

apache、nginx、php 隐藏版本号

apache、nginx、php 隐藏版本号 针对的系统都是CentOS 1、没配置之前 1.1 Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.2.24 mod_wsgi/3.4 Python/2.7.5 1.2 Server: nginx/1.16.0 1.3 X-Powered-By&#xff1a;7.2.24 2、配置信息 不知道具体位置&#xff0c;可…...

sqoop的安装与使用

Sqoop是一个用于在hadoop与mysql之间传输数据的工具 Sqoop 环境搭建 (1)上传安装包:sqoop-1.4.6-cdh5.14.2.tar.gz到/opt/software (2)解压安装包:tar -zxf sqoop-1.4.6-cdh5.14.2.tar.gz -C /opt/install/ (3)创建软连接:ln -s /opt/install/sqoop-1.4.6-cdh5.14.2/ /opt/ins…...

【docker】Docker Stack 详细使用及注意事项

一、什么是 Docker Stack Docker Stack 是 Docker Swarm 环境中用于管理一组相关服务的工具。它使得在 Swarm 集群中部署、管理和扩展一组相互关联的服务变得简单。主要用于定义和编排容器化应用的多个服务。以下是 Docker Stack 的一些关键特点&#xff1a; 服务集合&#xf…...

Android开发基础(四)

Android开发基础&#xff08;四&#xff09; 本篇将从Android数据存储方式去理解Android开发。 Android数据存储方式 Android提供了多种数据存储方式。 一、SharedPreferences存储 主要用于存储一些简单的配置信息&#xff0c;如登录账号密码等&#xff1b; 这种存储方式采…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...