每个管理后台都有一组权限菜单,根据不同的用户显示不同的权限,登录成功后,进入管理后台,左侧工作区是菜单栏显示,可以显示多级菜单
一、菜单显示效果图
如下图的红色框,这个就是菜单显示栏,下面针对这个菜单栏的实现进行详细讲解。
1-1:首页布局
二、首页布局
具体的效果参见上面的1-1:首页布局,如下是不就代码详解。
<div id="wrapper"> <!--左侧导航开始--> <nav class="navbar-default navbar-static-side" role="navigation"> </nav> <!--左侧导航结束--> <!--右侧部分开始--> <div id="page-wrapper" class="gray-bg dashbard-1"> </div> <!--右侧部分结束--> </div>
如上述代码片段,整个页面的布局拆分为两个工作空间,第一个工作空间是左侧导航栏,第二个工作栏是右侧工作区,右侧工作区根据不同的页面引入不同的html。
nav标签详解
<nav> 标签定义导航链接的部分。
并不是所有的 HTML 文档都要使用到 <nav> 元素。<nav> 元素只是作为标注一个导航链接的区域。
在不同设备上(手机或者PC)可以制定导航链接是否显示,以适应不同屏幕的需求。
三、左侧菜单栏实现
<ul class="nav" id="side-menu"> </ul>
右侧菜单栏使用ul列表标签进行显示。
其中 class ="nav" 使用bootstrap.min.css的样式,具体样式如下
.nav { padding-left: 0; margin-bottom: 0; list-style: none; }
左侧内边距和底部外边距都是0。
list-style: none 无列表样式。
3.1、个人信息栏目
效果图如下
实现代码:
<li> <div class="user-panel"> <a class="menuItem noactive" title="个人中心" th:href="@{/system/user/profile}"> <div class="hide" th:text="个人中心"></div> <div class="pull-left image"> <img th:src="(${#strings.isEmpty(user.avatar)}) ? @{/img/profile.jpg} : @{${user.avatar}}" th:onerror="this.src='img/profile.jpg'" class="img-circle" alt="User Image"> </div> </a> <div class="pull-left info"> <p>[[${user.loginName}]]</p> <a href="#"><i class="fa fa-circle text-success"></i> 在线</a> <a th:href="@{logout}" style="padding-left:5px;"><i class="fa fa-sign-out text-danger"></i> 注销</a> </div></div> </li>
3.1、动态菜单栏目
如下图,动态菜单包含一级菜单和二级菜单。系统管理是一级菜单,用户管理是二级菜单。
实现代码
<li th:each="menu : ${menus}"> <a th:class="@{${!#strings.isEmpty(menu.url) && menu.url != '#'} ? ${menu.target}}" th:href="@{${#strings.isEmpty(menu.url)} ? |#| : ${menu.url}}" th:data-refresh="${menu.isRefresh == '0'}"> <i class="fa fa-bar-chart-o" th:class="${menu.icon}"></i> <span class="nav-label" th:text="${menu.menuName}">一级菜单</span> <span th:class="${#strings.isEmpty(menu.url) || menu.url == '#'} ? |fa arrow|"></span> </a> <ul class="nav nav-second-level collapse"> <li th:each="cmenu : ${menu.children}"> <a th:if="${#lists.isEmpty(cmenu.children)}" th:class="${#strings.isEmpty(cmenu.target)} ? |menuItem| : ${cmenu.target}" th:utext="${cmenu.menuName}" th:href="@{${cmenu.url}}" th:data-refresh="${cmenu.isRefresh == '0'}">二级菜单</a> <a th:if="${not #lists.isEmpty(cmenu.children)}" href="#">[[${cmenu.menuName}]]<span class="fa arrow"></span></a> <ul th:if="${not #lists.isEmpty(cmenu.children)}" class="nav nav-third-level"> <li th:each="emenu : ${cmenu.children}"> <a th:if="${#lists.isEmpty(emenu.children)}" th:class="${#strings.isEmpty(emenu.target)} ? |menuItem| : ${emenu.target}" th:text="${emenu.menuName}" th:href="@{${emenu.url}}" th:data-refresh="${emenu.isRefresh == '0'}">三级菜单</a> <a th:if="${not #lists.isEmpty(emenu.children)}" href="#">[[${emenu.menuName}]]<span class="fa arrow"></span></a> <ul th:if="${not #lists.isEmpty(emenu.children)}" class="nav nav-four-level"> <li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${#strings.isEmpty(fmenu.target)} ? |menuItem| : ${fmenu.target}" th:text="${fmenu.menuName}" th:href="@{${fmenu.url}}" th:data-refresh="${fmenu.isRefresh == '0'}">四级菜单</a></li> </ul> </li> </ul> </li> </ul> </li>
从上述代码中,第一行menus是一个列表,循环列表,获取每一行的菜单数据。
第四行${menu.menuName} 显示菜单名称
第八行是循环menu对象下面的children列表,如果有二级菜单,那么循环显示二级菜单。
第十二行的逻辑是判断是否有三级菜单,如果有,那么继续循环显示三级菜单
通过Thymeleaf模版翻译后在浏览器显示的html
<li class="active"> <a href="#" data-refresh="false"> <i class="fa fa-gear"></i> <span class="nav-label">系统管理</span> <span class="fa arrow"></span></a> <ul class="nav nav-second-level collapse in" style="height: auto;"> <li><a class="menuItem" href="/system/user" data-refresh="false" data-index="2">用户管理</a></li> <li class="active selected"><a class="menuItem" href="/system/role" data-refresh="false" data-index="3">角色管理</a></li> <li><a class="menuItem" href="/system/menu" data-refresh="false" data-index="4">菜单管理</a></li> <li><a class="menuItem" href="/system/dept" data-refresh="false" data-index="5">部门管理</a></li> <li><a class="menuItem" href="/system/post" data-refresh="false" data-index="6">岗位管理</a></li> <li><a class="menuItem" href="/system/dict" data-refresh="false" data-index="7">字典管理</a></li> <li><a class="menuItem" href="/system/config" data-refresh="false" data-index="8">参数设置</a></li> <li><a class="menuItem" href="/system/notice" data-refresh="false" data-index="9">通知公告</a></li> <li><a href="#">日志管理<span class="fa arrow"></span></a><ul class="nav nav-third-level collapse"><li><a class="menuItem" href="/monitor/operlog" data-refresh="false" data-index="10">操作日志</a></li> <li><a class="menuItem" href="/monitor/logininfor" data-refresh="false" data-index="11">登录日志</a></li> </ul></li> </ul> </li>
menus数据的获取代码
在控制类里面将读取菜单的数据设置入ModelMap,Thymeleaf模版可以读取数据并显示。
如下是执行读取菜单的sql日志
11:03:15.646 [http-nio-28089-exec-94] DEBUG c.r.s.m.S.selectMenuNormalAll - [debug,137] - ==> Preparing: select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m where m.menu_type in ('M', 'C') and m.visible = 0 order by m.parent_id, m.order_num11:03:15.648 [http-nio-28089-exec-94] DEBUG c.r.s.m.S.selectMenuNormalAll - [debug,137] - ==> Parameters:11:03:15.656 [http-nio-28089-exec-94] DEBUG c.r.s.m.S.selectMenuNormalAll - [debug,137] - <== Total: 23
具体menus数据结构如下。
未来计划
1、ruoyi非分离版本拆解
2、ruoyi-vue-pro:讲解工作流
3、ruoyi-vue-pro:支付模块,电商模块
4、基于ruoyi-vue-pro项目开发
5、JEECG低代码开发平台
请关注我,本星球会持续推出更多的开源项目代码解析,如有更好的意见请留言回复或者私信。
来源:
互联网
本文观点不代表源码解析立场,不承担法律责任,文章及观点也不构成任何投资意见。
评论列表