SSM——Vue树形菜单的实现

该博客围绕实现Vue多级菜单渲染展开,介绍了数据库设计,如tb_menus数据表;阐述后端核心代码,包括Menus实体类、IMenusDao和MenusController,还提及mybatis懒加载的坑;前端核心代码通过v - for遍历实现。最后总结项目采坑经历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、需求

实现Vue多级菜单的渲染

效果图:
在这里插入图片描述

json数据格式,使用postman模拟如下:
在这里插入图片描述

二、数据库设计

tb_menus数据表
在这里插入图片描述
内容
在这里插入图片描述

三、后端核心代码

1.Menus实体类

package com.mall.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * 菜单实体类
 *
 * @author : Bei-Zhen
 */
@JsonIgnoreProperties(value = {"handler"})
public class Menus implements Serializable {

    /**
     * 菜单id
     */
    private Integer id;
    /**
     * 父级id
     */
    private Integer parentId;
    /**
     * 菜单名称
     */
    private String name;
    /**
     * 菜单图片
     */
    private String img;
    /**
     * 是否可用
     */
    private Integer status;
    /**
     * 创建时间
     */
    private Date created;

    /**
     * 子节点集合
     */
    private List<Menus> children;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }


    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }


    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }


    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public List<Menus> getChildren() {
        return children;
    }

    public void setChildren(List<Menus> children) {
        this.children = children;
    }

    @Override
    public String toString() {
        return "Menus{" +
                "id=" + id +
                ", parentId=" + parentId +
                ", name='" + name + '\'' +
                ", img='" + img + '\'' +
                ", status=" + status +
                ", created=" + created +
                ", children=" + children +
                '}';
    }
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201229124839463.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNTkxODcz,size_16,color_FFFFFF,t_70)

注意:假如用了mybatis懒加载必须加上这个注解,不然会报错,这里是个很大的坑
在这里插入图片描述
因为mybatis配置懒加载导致返回对象Jackson解析失败。
在这里插入图片描述
报错代码

org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.HashMap["data"]->java.util.ArrayList[0]->com.mall.domain.Menus_$$_jvst624_0["children"]->java.util.ArrayList[0]->com.mall.domain.Menus_$$_jvst624_0["handler"])!

2.IMenusDao:思路为利用一对多关系,先用getTree()查出所有父节点,再利用listChild()递归查出所有子节点渲染树形菜单

package com.mall.dao;

import com.mall.domain.Menus;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 菜单的持久层接口
 * @author : Bei-Zhen
 * @date : 2020-12-28 15:19
 */
@Repository
public interface IMenusDao {

    /**
     * 查询菜单父节点
     * @return
     */
    @Results(id = "menusMap",
            value = {
                    @Result(id = true,property = "id",column = "id"),
                    @Result(property = "parentId", column = "parent_id"),
                    @Result(column = "id",
                            property = "children",
                            many = @Many(select = "com.mall.dao.IMenusDao.listChild",fetchType = FetchType.LAZY)
                    )
            })
    @Select("select * from tb_menus where parent_id=0")
    List<Menus> getTree();

    /**
     * 查询菜单子节点
     * @param parentId
     * @return
     */
    @ResultMap("menusMap")
    @Select("select * from tb_menus where parent_id=#{parentId}")
    List<Menus> listChild(@Param("parentId")int parentId);
}

3.MenusController

package com.mall.controller;

import com.mall.domain.Menus;
import com.mall.service.IMenusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author : Bei-Zhen
 * @date : 2020-12-26 11:51
 */
@Controller
public class MenusController {

    @Autowired
    private IMenusService menusService;

    /**
     * 测试
     * @param
     * @return
     */
    @RequestMapping("/menus")
    public  @ResponseBody
    Map<String,Object> getMenus() {
        Map<String,Object> menusMap = new HashMap<>();
        //获取菜单集合
        List<Menus> menus = menusService.getTree();
        //放入Map集合
        menusMap.put("data",menus);
        //创建状态Map
        Map<String,Object> metaMap = new HashMap<>();
        metaMap.put("msg","获取菜单列表成功");
        metaMap.put("status",200);
        menusMap.put("meta",metaMap);
        return menusMap;
    }
}

四、前端核心代码

通过v-for遍历
在这里插入图片描述

五、总结

这是做vue+ssm商城项目,才开始几天的第三个坑了,跨域、token、树形菜单的渲染,收获挺大的,不断采坑中…
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bei-zhen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值