Java后端 || ElementUI 显示后端树形表格数据

news2024/10/5 21:16:33

文章目录

  • 1、前端源码
  • 2、数据库设计
  • 3、后端设计
    • 3.1、实体类
    • 3.2、Controller层
    • 3.3、具体树形列表后端代码实现

1、前端源码

ElementUI Table 链接

在此链接中找到 树形数据与懒加载

在这里插入图片描述
查看其JS源码,可知,每个菜单节点的子节点存放于children字段中,

const tableData: User[] = [
  {
    id: 1,
    date: '2016-05-02',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    id: 2,
    date: '2016-05-04',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    id: 3,
    date: '2016-05-01',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
    children: [
      {
        id: 31,
        date: '2016-05-01',
        name: 'wangxiaohu',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        id: 32,
        date: '2016-05-01',
        name: 'wangxiaohu',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ],
  },
  {
    id: 4,
    date: '2016-05-03',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
]

将示例代码复制到项目中,此处根据源码做了符合自己项目的修改,主要复制el-table中的内容

<el-table
        :data="list"
        style="width: 100%; margin-bottom: 20px"
        row-key="id"
        border
        default-expand-all
    >
    <el-table-column prop="title" label="菜单标题" />
    <el-table-column prop="component" label="路由名称" />
    <el-table-column prop="sortValue" label="排序" />
    <el-table-column prop="status" label="状态" #default="scope">
      {{ scope.row.status == 1 ? '正常' : '停用' }}
    </el-table-column>
    <el-table-column prop="createTime" label="创建时间" />

    <el-table-column label="操作" align="center" width="280" #default="scope" >
        <el-button type="success" size="small" @click="addShow(scope.row)">
            添加下级节点
        </el-button>
        <el-button type="primary" size="small" @click="editShow(scope.row)">
            修改
        </el-button>
        <el-button type="danger" size="small" @click="remove(scope.row.id)">
            删除
        </el-button>
    </el-table-column>
  </el-table>

<script setup>
import { ref , onMounted } from "vue"

// 定义表格数据模型
const list = ref([])
//页面表单数据
const defaultForm = {
    id: '',
    parentId: 0,
    title: '',
    url: '',
    component: '',
    icon: '',
    sortValue: 1,
    status: 1,
}

// 钩子函数
onMounted(() => {
    fetchData()
})

const fetchData = async () => {
    const { code, data, message } = await FindNodes()
    list.value = data
}
</script>

前端js配置文件

import request from '@/utils/request'
const api_name = '/admin/system/sysMenu'

export const FindNodes = () => {
    return request({
        url: `${api_name}/findNodes`,
        method: 'get',
    })
}

2、数据库设计

每个菜单有自己的id,还有其父节点的parent_id(用于表示父子关系,双亲表示法)
在这里插入图片描述
给出SQL DDL 注:基于MySQL 8.0.30

CREATE TABLE `sys_menu` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  `parent_id` bigint NOT NULL DEFAULT '0' COMMENT '所属上级',
  `title` varchar(20) NOT NULL DEFAULT '' COMMENT '菜单标题',
  `component` varchar(100) DEFAULT NULL COMMENT '组件名称',
  `sort_value` int NOT NULL DEFAULT '1' COMMENT '排序',
  `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(0:禁止,1:正常)',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='菜单表'

3、后端设计

3.1、实体类

这边先把公共的属性抽取出来 组成BaseEntity类,然后将菜单的属性定义在SysMenu类,并继承BaseEntity

// BaseEntity 类

@Data
public class BaseEntity implements Serializable {

    @Schema(description = "唯一标识")
    private Long id;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "创建时间")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "修改时间")
    private Date updateTime;

    @Schema(description = "是否删除")
    private Integer isDeleted;

}
// SysMenu 类

@Data
public class SysMenu extends BaseEntity {

	@Schema(description = "父节点id")
	private Long parentId;

	@Schema(description = "节点标题")
	private String title;

	@Schema(description = "组件名称")
	private String component;

	@Schema(description = "排序值")
	private Integer sortValue;

	@Schema(description = "状态(0:禁止,1:正常)")
	private Integer status;

	// 下级列表
	@Schema(description = "子节点")
	private List<SysMenu> children;

}

3.2、Controller层

常规调用,注意"/findNodes"路径与前端js文件中保持一致

// 显示菜单列表方法
@GetMapping("/findNodes")
public Result findNodes(){
    List<SysMenu> sysMenuList = sysMenuService.findNodes();
    return Result.build(sysMenuList, ResultCodeEnum.SUCCESS);
}

3.3、具体树形列表后端代码实现

代码3.1为实现类中的方法,此代码中sysMenuMapper.findAll() 用于查询所有菜单,其SQL如下
select * from sys_menu where is_deleted = 0 order by sort_value

此外,其中的MenuHelper为自定义的一个类,在代码3.2中给出,该类的静态方法buildTree为具体的递归构造树形菜单的方法(该方法的参数为:菜单列表数据)。

buildTree方法调用了递归函数findChildren(该递归函数的参数为:已知的父节点,菜单列表数据),其思路是:已知的父节点为N0,再找出子节点N1,并递归地为N1节点的children属性赋值,然后将N1添加至N0的children中。

代码3.1:

// 递归查找列表
@Override
public List<SysMenu> findNodes() {
    // 1.先查询所有菜单,返回所有list集合
    List<SysMenu> sysMenuList = sysMenuMapper.findAll();
    if (CollectionUtils.isEmpty(sysMenuList)){
        return null;
    }

    // 2.调用工具类中的方法,返回树形数据结构列表
    List<SysMenu> treeList = MenuHelper.buildTree(sysMenuList);
    return treeList;
}

代码3.2:

public class MenuHelper {

    // 递归实现封装
    public static List<SysMenu> buildTree(List<SysMenu> sysMenuList){
        // TODO 完成封装过程
        List<SysMenu> trees = new ArrayList<>();

        for (SysMenu sysMenu : sysMenuList) {
            // 找到递归入口
            if (sysMenu.getParentId().longValue()==0){
                // 根据第一层,找下一层的数据
                trees.add(findChildren(sysMenu, sysMenuList));
            }
        }

        return trees;
    }


    // 返回已经封装好children字段的 菜单节点
    private static SysMenu findChildren(SysMenu sysMenu, List<SysMenu> sysMenuList) {
        // 初始化
        sysMenu.setChildren(new ArrayList<>());

        for (SysMenu menu : sysMenuList) {
            if(menu.getParentId().longValue()==sysMenu.getId().longValue()){
                sysMenu.getChildren().add(findChildren(menu, sysMenuList));
            }
        }

        return sysMenu;
    }
}

最终效果:

在这里插入图片描述

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

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

相关文章

直播分享|TinyVue 组件库主题适配原理与实战

在前端开发过程中&#xff0c;不同的项目可能需要不同的设计风格。而了解组件库的主题适配功能&#xff0c;也可以帮助开发者轻松定制独特的主题风格&#xff0c;从而满足各种设计需求。因此6月27日晚19点&#xff0c;体验技术团队 TinyVue 项目成员岑灌铭老师将为大家带来以《…

▶《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch5 蒙特卡洛方法【model-based ——> model-free】

PPT 截取必要信息。 课程网站做习题。总体 MOOC 过一遍 1、视频 学堂在线 习题 2、 过 电子书 是否遗漏 【下载&#xff1a;本章 PDF GitHub 页面链接 】 【第二轮 才整理的&#xff0c;忘光了。。。又看了一遍视频】 3、 过 MOOC 习题 看 PDF 迷迷糊糊&#xff0c; 恍恍惚惚。…

Swift 周报 第五十五期

文章目录 前言新闻和社区苹果公司据悉将推出密码管理应用三大指数涨跌不一&#xff0c;苹果重新夺回美股第二大上市公司宝座苹果iOS 18新动向&#xff1a;AI功能强化隐私保护&#xff0c;用户自主选择启用 提案通过的提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言…

springboot + Vue前后端项目(第十九记)

项目实战第十九记 写在前面1. redis安装(windows安装)1.1 获取软件链接地址&#xff1a;1.2 启动redis1.3 测试是否启动成功1.4 通过 Another Redis DeskTop软件可视化查看redis 2. SpringBoot集成redis2.1 引入依赖2.2 注入RedisTemplate2.3 使用redis2.4 redis更新2.5 redis使…

【经验分享】Claude3.5 Sonnet六大可扩展用途

Claude3.5 Sonnet六大可扩展用途 概述 Claude 3.5 Sonnet的性能比其他大模型都有好&#xff0c;本文基于Claude3.5 Sonnet的Artifact功能进行讨论和分析&#xff0c;提供了Claude3.5 Sonnet的六大可扩展用途。 用途 1.画SVG图像 2.设计网站 3.设计徽标 4.设计游戏 5.分…

JavaScript的学习之dom的查询(一)

一、获得元素 通过document对象调用&#xff1a; getElementById()&#xff1a;通过id属性获取一个元素节点对象getElementsByTagName()&#xff1a;通过标签名获取一组元素节点对象getElementsByName()&#xff1a;通过name属性来获取一组元素节点对象 核心学习代码 <scrip…

【语义分割】1-标注数据集-【单张图片】labelme标注json文件转mask

声明&#xff1a;我学习了b站&#xff1a;标注自己的语义分割数据集_哔哩哔哩_bilibili 并且复现了&#xff0c;记录了所思所得。 主要是说了&#xff1a; 做语义分割&#xff0c;数据集怎么用labelme标注成json文件&#xff0c;以及&#xff0c;json文件怎么转成mask 流程…

springcould-config git源情况下报错app仓库找不到

在使用spring config server服务的时候发现在启动之后的一段时间内控制台会抛出异常&#xff0c;spring admin监控爆红&#xff0c;控制台信息如下 --2024-06-26 20:38:59.615 - WARN 2944 --- [oundedElastic-7] o.s.c.c.s.e.JGitEnvironmentRepository : Error occured …

Linux - 记一次某Java程序启动报错(申请内存失败)

文章目录 问题可能原因分析可能原因分析尝试各种解决方案尝试解决过程 解决办法&#xff1a; 调整 overcommit_meory参数overcommit_memory详解什么是 overcommit_memory&#xff1f;overcommit_memory 的选项及其含义配置 overcommit_memory查看当前设置设置 overcommit_memor…

如何为您的企业实施营销翻译

要为您的业务实施营销翻译&#xff0c;您需要执行以下步骤&#xff1a; 评估市场需求 你首先需要做的事情之一是确定你的产品或服务可以销售的地区或国家。这可以通过 看看在这些地区已经取得成功的竞争对手阅读行业的市场调查和预测&#xff0c;了解市场趋势和潜在机会评估…

经销or直营,新老车企殊途终要同归

步入2024&#xff0c;汽车圈的新人、老人都逐渐活成了对方的样子。 2024年5月&#xff0c;先后有消息传来&#xff0c;阿维塔要从直营模式全部转向经销模式&#xff0c;蔚来新发布的子品牌“乐道”未来可能考虑合作或加盟&#xff0c;并单独建设门店。 而就在5月1日&#xff…

网工内推 | 国企信息工程师,信息系统项目管理师优先,最高14薪

01 上海浦东软件园股份有限公司 &#x1f537;招聘岗位&#xff1a;信息化管理工程师 &#x1f537;岗位职责&#xff1a; 1. 根据公司战略、数字化总体架构规划和IT 技术趋势&#xff0c;制定信息化系统的规划与设计&#xff0c;并制定实施计划。 2. 统筹公司信息化系统管理…

ONLYOFFICE 文档 8.1 发布:重塑文档处理

官网链接&#xff1a;ONLYOFFICE官网 一、PDF编辑器功能强大&#xff1a;创造跟随想象 在追求无界办公与高效创作的今天&#xff0c;ONLYOFFICE再次引领风潮&#xff0c;正式发布了其桌面编辑器的最新版本——ONLYOFFICE桌面编辑器8.1。这一版本不仅巩固了其作为顶级办公套件…

【分布式文件系统HDFS】文件操作基本命令的使用

目录 一、按照下述要求写出相应的文件操作命令&#xff0c;执行并观察结果 1. 新建目录 1.1 在本地文件系统按要求创建如下的文件夹 1.2 在HDFS文件系统按要求创建如下的文件夹 2. 编辑文件test1.txt&#xff0c;放入本地文件夹 /opt/user/myfile 3. 使用moveFromLocal命令…

计算机视觉:项目实战

目录 SSD1.安装ananconda2.安装cuda和cudnn3.配置Pytorch环境3.1 pytorch环境的配置与激活3.2 pytorch库的安装3.3 其它依赖库的安装 遇到的问题&#xff1a;1.EOFError: Ran out of input.2.No module named dlib. SSD 1.安装ananconda 见另一篇博文&#xff1a;https://blo…

随机步问题

随机步问题 1.题目简介2.题目分析3.创建变量4.主程序5.程序效果6.程序可以改进的点 1.题目简介 2.题目分析 数组初始化 生成随机方向 判断程序结束的标志 当前元素为Z&#xff0c;或者四个方向都堵住了 3.创建变量 arry[ROW][COL]创建二维数组 _Bool a,b,c,d判断是否会出现四…

搜索引擎的妙用:掌握这些技巧,让你的搜索更高效!

搜索引擎是我们日常生活中不可或缺的工具&#xff0c;它帮助我们快速找到所需的信息。但是&#xff0c;你真的知道如何高效地使用搜索引擎吗&#xff1f;下面&#xff0c;我将分享一些高级搜索技巧&#xff0c;让你的搜索更加精准和高效。 1. 完全匹配搜索 当你想要搜索一个特…

Python数据可视化-地图可视化

1.首先绘制实现数据可视化的思维导图 具体要实现什么功能-怎么处理&#xff0c;先把思路写好 数据来源&#xff1a; 爬取的数据 运行结果&#xff1a; 部分代码&#xff1a; 完整代码请在下方↓↓↓&#x1f447;获取 转载请注明出处&#xff01;

调频信号FM的原理与matlab与FPGA实现

平台&#xff1a;matlab r2021b&#xff0c;vivado2023.1 本文知识内容摘自《软件无线电原理和应用》 调频(FM)是载波的瞬时频率随调制信号成线性变化的一种调制方式&#xff0c;音频调频信号的数学表达式可以写为&#xff1a; Fm频率调制&#xff0c;载波的幅度随着调制波形…

不同材质的不锈钢氮气柜优缺点和使用场景分析

不锈钢氮气柜是一种用于存储对湿度敏感的物品的专用储藏设备&#xff0c;通过充入干燥的氮气来降低柜内湿度&#xff0c;保护存储物免受氧化或腐蚀。 根据不同的材质&#xff0c;不锈钢氮气柜可分为&#xff1a; 一、201不锈钢氮气柜&#xff1a; 201不锈钢因其较低的镍含量而成…