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

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;
    }
}

最终效果:

在这里插入图片描述

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在HTML表格显示后端Java数据,你需要进行以下步骤: 1. 从Java后端获取数据:使用Java中的数据库连接技术(如JDBC)或者Web框架(如Spring)从数据库中获取数据。 2. 将数据转换成HTML格式:使用Java中的字符串拼接或者模板引擎(如FreeMarker)将数据转换成HTML格式。 3. 在HTML中展示数据:在HTML中使用表格(table)标签来展示数据。你可以通过JavaScript或者AJAX技术来异步获取数据并更新表格。 以下是一个基本的示例代码: Java代码: ```java // 获取数据库连接 Connection conn = DriverManager.getConnection(url, username, password); // 查询数据 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users"); // 将数据转换成HTML格式 StringBuilder htmlBuilder = new StringBuilder(); while (rs.next()) { htmlBuilder.append("<tr>"); htmlBuilder.append("<td>").append(rs.getString("id")).append("</td>"); htmlBuilder.append("<td>").append(rs.getString("name")).append("</td>"); htmlBuilder.append("<td>").append(rs.getString("email")).append("</td>"); htmlBuilder.append("</tr>"); } String html = htmlBuilder.toString(); // 关闭连接 rs.close(); stmt.close(); conn.close(); // 将HTML数据返回给前端 return html; ``` HTML代码: ```html <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Email</th> </tr> </thead> <tbody id="tableBody"> <!-- 数据将被动态添加到这里 --> </tbody> </table> <script> // 异步获取数据并更新表格 fetch('/api/users') .then(response => response.text()) .then(html => { document.getElementById('tableBody').innerHTML = html; }); </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值