利用thymeleaf的block标签实现递归展示多级菜单
程序员文章站
2022-07-08 11:25:59
...
如题,借助thymeleaf的标签将多级菜单递归展示到页面上。网上查阅了多个博客,均不太适合我的需求。
这里,我主要用到的是<th:block>标签里面的“th:include”属性,将其值设置为递归函数,并传入初始参数。通过设置“th:unless”属性,添加递归结束条件。
关键代码如下:
1、后端菜单数据结构:
MenuVO
/** * 菜单信息封装对象 * * @ClassName: MenuVO * @Description: TODO * */ public class MenuVO implements Serializable { private static final long serialVersionUID = 6979431459397881571L; /** * 菜单id */ private Integer menuId; /** * 菜单名字 */ private String menuName; /** * 菜单顺序 */ private Integer menuOrder; /** * 菜单对应页面地址 */ private String url; /** * 菜单图标 */ private String icon; /** * 子菜单集合 */ private List<MenuVO> children; /** * 菜单类型:0、目录;1、菜单、2、按钮 */ private Integer type; //其他代码略... }
2、在controller中返回的数据模型中写入MenuVO集合
@Controller public class LoginController extends BaseController{ @Autowired MenuService menuService; @GetMapping({ "/index" }) String index(Model model) { List<MenuVO> menus = menuService.queryMenusByUserId(getUserId()); model.addAttribute("menus", menus); model.addAttribute("name", getUser().getName()); return "index"; } //其他代码略...... }
3、添加菜单代码块
footer.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <th:block th:fragment="menu2(menus,lv)"> <th:block th:each="p : ${menus}"> <li> <a th:url="${p.url}" th:style="|padding-left:${13*lv}px|" th:href="'#menu'+${p.menuId}" class="menuItem collapsed" data-toggle="collapse"><i th:class="${p.icon}" aria-hidden="true"></i> <span th:text="${p.menuName}"></span> <span th:if="${p.type} ==0" class="pull-right glyphicon glyphicon-chevron-toggle"></span> </a> <ul th:if="${p.type} ==0" th:id="'menu'+${p.menuId}" class="nav nav-list collapse" style="height: 0px;"> <th:block th:unless="${#lists.isEmpty(p.children)}" th:include="this::menu2(${p.children},${lv+1})"/> </ul> </li> </th:block> </th:block> </body> </html>
4、在index.html页面中引用菜单代码块
<!-- 菜单导航 --> <div class="menu col-md-2 shadow"> <ul id="main-nav" class="nav nav-stacked" style=""> <th:block th:include="footer::menu2(${menus},1)"/> </ul> </div>