一.用layui及mini做一个初步的导航栏加菜单栏框架。

       layuimini目前是开源的前端框架。目前有两种思路。第一种是用接口,让layuimini读取接口中的菜单栏初始化,一种是用model映射。

        我用的模板引擎是thymeleaf。

1.(制作页面第一种方法)用model映射做导航栏和菜单栏

        这种适合有js基础的人,因为很多东西都要参考layuimini的基础重做js,否则无法将导航栏,菜单栏,菜单历史导航同步。先看数据库设计:

DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu`  (
  `pk_menu_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `menu_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标题',
  `menu_href` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '链接',
  `parent_id` bigint(0) NOT NULL COMMENT '父级菜单ID',
  `icon` varchar(10000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图标',
  `authority` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限标识符',
  `sort` smallint(0) NULL DEFAULT NULL COMMENT '排序值',
  `type` tinyint(0) NOT NULL COMMENT '类型[1:目录, 2:菜单, 3:按钮]',
  `status` bit(1) NULL DEFAULT NULL COMMENT '是否显示',
  `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
  `target` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '页面跳转方式',
  `create_by` bigint(0) NULL DEFAULT NULL COMMENT '创建人',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` bigint(0) NULL DEFAULT NULL COMMENT '更新人',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`pk_menu_id`) USING BTREE,
  UNIQUE INDEX `idx_menu_title`(`menu_title`) USING BTREE,
  INDEX `idx_menu_pid`(`parent_id`) USING BTREE,
  INDEX `idx_menu_sort`(`sort`) USING BTREE,
  INDEX `idx_menu_href`(`menu_href`) USING BTREE,
  INDEX `idx_menu_authority`(`authority`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 88 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

        可用Mybatisplus,然后自己写个递归将菜单栏做成树形json数据结构,返回到前端进行接收。

 <resultMap id="MenuResultMap" type="com.coolbusiness.coolbusiness.system.entity.Menu" >
        <id column="pk_menu_id" jdbcType="BIGINT" property="pkMenuId"/>
        <result column="menu_title" jdbcType="VARCHAR" property="menuTitle"/>
        <result column="menu_href" jdbcType="VARCHAR" property="menuHref"/>
        <result column="parent_id" jdbcType="BIGINT" property="parentId"/>
        <result column="icon" jdbcType="VARCHAR" property="icon"/>
        <result column="authority" jdbcType="VARCHAR" property="authority"/>
        <result column="sort" jdbcType="SMALLINT" property="sort"/>
        <result column="type" jdbcType="TINYINT" property="type"/>
        <result column="status" jdbcType="BIT" property="status"/>
        <result column="remark" jdbcType="VARCHAR" property="remark"/>
        <result column="target" jdbcType="VARCHAR" property="target"/>
        <result column="create_by" jdbcType="BIGINT" property="createBy"/>
        <result column="create_time" jdbcType="DATE" property="createTime"/>
        <result column="update_by" jdbcType="BIGINT" property="updateBy"/>
        <result column="update_time" jdbcType="DATE" property="updateTime"/>
    </resultMap>

 <select id="ListParent" resultMap="MenuResultMap">
        select * from sys_menu where type=1
    </select>

    <select id="ListChildren" resultMap="MenuResultMap"  parameterType="integer" >
        select * from sys_menu where parent_id=${id}
    </select>

JAVA代码部分:

DAO层

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.coolbusiness.coolbusiness.system.entity.Menu;
import com.coolbusiness.coolbusiness.system.entity.sysMenu;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;

@Mapper
@Repository
public interface MenuDao extends BaseMapper<Menu> {

    /**
     * 获取导航栏的全部内容,用于加载页面
     * @return
     */
    public List<Menu> ListParent();

    /**
     * 获取子菜单内容
     * @return
     */
    public List<Menu> ListChildren(@Param("id") Integer id);
}

service层:

import com.coolbusiness.coolbusiness.Constants.Constant;
import com.coolbusiness.coolbusiness.system.dao.MenuDao;
import com.coolbusiness.coolbusiness.system.entity.Menu;
import com.coolbusiness.coolbusiness.system.entity.sysMenu;
import com.coolbusiness.coolbusiness.system.service.MenuService;
import com.coolbusiness.coolbusiness.system.utils.TreeUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * author baiyang
 * 2021-10-01
 */
@Transactional
@Service("MenuService")
public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuDao menuDao;

    @Override
    public List<Menu> ListAll() {
        List<Menu> menuList =  menuDao.ListParent();
        //获取子节点childrenList
        for (Menu menu : menuList){
            getChildrenList(menu);
        }
        return menuList;
    }

    public void getChildrenList(Menu menu){
        List<Menu> children = menuDao.ListChildren(menu.getPkMenuId());
        menu.setChildren(children);
        if(children.size()>0 && children!=null )
        for (Menu menuChild : children){
            getChildrenList(menuChild);
        }
    }
}

controller层:

import com.coolbusiness.coolbusiness.DIYException.BadRequestException;
import com.coolbusiness.coolbusiness.system.entity.Menu;
import com.coolbusiness.coolbusiness.system.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

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

@Controller
@RequestMapping("/login")
public class indexController {

    @Autowired
    private MenuService menuService;

    @GetMapping("/index")
    public String indexHTML(Model model){
        List<Menu> menuList = menuService.ListAll();
        if(menuList!=null && menuList.size()>0 ){
            model.addAttribute("menuList", menuList);
        }else{
            throw new BadRequestException("--->你的菜单内容为空,请检查!");
        }
        return "index";
    }
}

前端页面直接在页面中用标签进行接收即可,代码如下:

index.html:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<html>
<head>
    <meta charset="utf-8">
    <title>layuimini-iframe版 v2 - 基于Layui的后台管理系统前端模板</title>
    <meta name="keywords" content="layuimini,layui,layui模板,layui后台,后台模板,admin,admin模板,layui mini">
    <meta name="description" content="layuimini基于layui的轻量级前端后台管理框架,最简洁、易用的后台框架模板,面向所有层次的前后端程序,只需提供一个接口就直接初始化整个框架,无需复杂操作。">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="icon" href="images/favicon.ico">

    <link rel="stylesheet" href="/plugin/layuimini-v2/lib/layui-v2.6.3/css/layui.css" media="all">
    <link rel="stylesheet" href="/plugin/layuimini-v2/css/layuimini.css?v=2.0.4.2" media="all">
    <link rel="stylesheet" href="/plugin/layuimini-v2/css/themes/default.css" media="all">
    <link rel="stylesheet" href="/plugin/layuimini-v2/lib/font-awesome-4.7.0/css/font-awesome.min.css" media="all">

    <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style id="layuimini-bg-color">
    </style>
</head>
<body class="layui-layout-body layuimini-all">
<div class="layui-layout layui-layout-admin">

    <div class="layui-header">
        <div class="layui-logo layuimini-logo">
        	
        </div>

        <div class="layuimini-header-content">
            <a>
                <div class="layuimini-tool"><i title="展开" class="fa fa-outdent" data-side-fold="1"></i></div>
            </a>

            <!--电脑端头部菜单-->
            <ul class="layui-nav layui-layout-left layuimini-header-menu layuimini-pc-show ">
                <li th:data-menu="'multi_module_'+${itemStat.index}" th:each="item, itemStat :${menuList}"
                    th:if="${item.type}==1"
                    th:class="'layui-nav-item layui-hide-xs ' + (${itemStat.index eq 0} ? 'layui-this' : '')"
                    th:id="'multi_module_'+${itemStat.index}+'HeaderId'" >
                    <a href="javascript:;">
                        <span class="layui-left-nav"  th:text="${item.menuTitle}"></span>
                    </a>
                </li>
            </ul>

            <!--手机端头部菜单-->
            <ul class="layui-nav layui-layout-left layuimini-header-menu layuimini-mobile-show">
                 <li class="layui-nav-item">
                    <a href="javascript:;"><i class="fa fa-list-ul"></i> 选择模块</a>
                    <dl class="layui-nav-child layuimini-menu-header-mobile">
                   		 <dd th:each="item, itemStat :${menuList}"
                   			 th:if="${item.type}==1"
                    		 th:class="'menu-dd undefined undefined ' + (${itemStat.index eq 0} ? 'layui-this' : '')">
                    <a 	href="javascript:;" th:data-menu="'multi_module_'+${itemStat.index}" 
                    	th:id="'multi_module_'+${itemStat.index}+'HeaderId'">
                        <span class="layui-left-nav"  th:text="${item.menuTitle}"></span>
                    </a>
                	</dd>
                    </dl>
                </li>
            </ul>

            <ul class="layui-nav layui-layout-right">

                <li class="layui-nav-item" lay-unselect>
                    <a href="javascript:;" data-refresh="刷新"><i class="fa fa-refresh"></i></a>
                </li>
                <li class="layui-nav-item" lay-unselect>
                    <a href="javascript:;" data-clear="清理" class="layuimini-clear"><i class="fa fa-trash-o"></i></a>
                </li>
                <li class="layui-nav-item mobile layui-hide-xs" lay-unselect>
                    <a href="javascript:;" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a>
                </li>
                <li class="layui-nav-item layuimini-setting">
                    <a href="javascript:;">admin</a>
                    <dl class="layui-nav-child">
                        <dd>
                            <a href="javascript:;" layuimini-content-href="/plugin/layuimini-v2/page/user-setting.html" data-title="基本资料" data-icon="fa fa-gears">基本资料<span class="layui-badge-dot"></span></a>
                        </dd>
                        <dd>
                            <a href="javascript:;" layuimini-content-href="/plugin/layuimini-v2/page/user-password.html" data-title="修改密码" data-icon="fa fa-gears">修改密码</a>
                        </dd>
                        <dd>
                            <hr>
                        </dd>
                        <dd>
                            <a href="javascript:;" class="login-out">退出登录</a>
                        </dd>
                    </dl>
                </li>
                <li class="layui-nav-item layuimini-select-bgcolor" lay-unselect>
                    <a href="javascript:;" data-bgcolor="配色方案"><i class="fa fa-ellipsis-v"></i></a>
                </li>
            </ul>
        </div>
    </div>



    <!--无限极左侧菜单-->
    <div class="layui-side layui-bg-black layuimini-menu-left">
        <div class="layui-side-scroll">
            <ul  th:each="item ,itemStat:${menuList}"
                 th:if="${item.status}==1 "
                 th:class="'layui-nav layui-nav-tree layui-left-nav-tree ' + (${itemStat.index > 0} ? 'layui-hide' : '')"
                 th:id="'multi_module_'+${itemStat.index}">

            <li th:each="subItem, subStat:${item.children}"
                th:if="${subItem.parentId}==${item.pkMenuId} and ${subItem.status}==1 "
                th:id="'multi_module_'+${itemStat.index}" class="layui-nav-item menu-li">
                <!--th:text="(${subItem.status}=='1'? ' true ':' false ')
                   +' '+ (${subItem.target}=='1'? ' true ':' false ')
                   +' '+(${subItem.menuHref}eq'#'? ' true ':' false ')
                   + ${subItem.menuTitle}+ ' '+${subStat.size}"  th:text的属性是将文本中的内容进行替换,显示 文本内容时不要在li里面放th:text-->

                <a th:if="${subItem.status}=='1' and ${subItem.target}=='1' and ${subItem.menuHref} ne '#'"
                   th:href="${subItem.menuHref}" target="_blank">
                    <i th:class="'fa '+${subItem.icon}"></i>&emsp;
                   <!-- <cite th:text="{subItem.menuTitle}"></cite> -->
                    <span class="layui-left-nav" th:text="${subItem.menuTitle} "></span>
                </a>

                <a th:if="${subItem.status}=='1' and ${subItem.target} == '2' and ${subItem.menuHref} ne '#' "
                   th:lay-href="${subItem.menuHref}">
                    <i th:class="'fa '+${subItem.icon}"></i>&emsp;
                   <!--  <cite th:text="${subItem.menuTitle}"></cite> -->
                    <span class="layui-left-nav" th:text="${subItem.menuTitle}"></span>
                </a>

                <a th:if="${subItem.menuHref}eq'#'">
                    <i th:class="'fa '+${subItem.icon}"></i>&emsp;
                   <!--  <cite th:text="${subItem.menuTitle}"></cite> -->
                    <span class="layui-left-nav" th:text="${subItem.menuTitle}"></span>
                </a>

                <dl th:if="${not #lists.isEmpty(subItem.children)}" class="layui-nav-child">
                    <dd th:if="${nextItem.menuHref} ne '#'" th:each="nextItem ,nextItemStat : ${subItem.children}">
                        <a th:lay-href="${nextItem.menuHref}" th:text="${nextItem.menuTitle}+${nextItem.menuHref}"> </a>
                    </dd>
                    <dd th:if="${nextItem.menuHref} eq '#'" th:each="nextItem ,nextItemStat : ${subItem.children}">
                        <a th:text="${nextItem.menuTitle}"> </a>
                        <dl th:if="${not #lists.isEmpty(nextItem.children)}" class="layui-nav-child">
                            <dd th:each="_nextItem, _nextItemStat : ${nextItem.children}">
                                <a th:lay-href="${nextItem.menuHref}" th:text="${_nextItem.menuTitle} ${nextItem.menuHref}"></a>
                            </dd>
                        </dl>
                    </dd>
                </dl>
             </li>
            </ul>
        </div>
    </div>

<!--    初始化加载层 这里要注释了,不然一直加载接口,这个可以通过见接口注释解决,或者是参数在后端写好后可以放开-->
<!--    <div class="layuimini-loader">-->
<!--        <div class="layuimini-loader-inner"></div>-->
<!--    </div>-->

    <!--手机端遮罩层-->
    <div class="layuimini-make">

    </div>

    <!-- 移动导航 -->
    <div class="layuimini-site-mobile"><i class="layui-icon"></i></div>

    <div class="layui-body">

        <div class="layuimini-tab layui-tab-rollTool layui-tab" lay-filter="layuiminiTab" lay-allowclose="true">
        
            <ul class="layui-tab-title">
                <li class="layui-this" id="layuiminiHomeTabId" lay-id=""></li>
            </ul>
            <!-- 这里是导航栏 -->
            <div class="layui-tab-control">
                <li class="layuimini-tab-roll-left layui-icon layui-icon-left"></li>
                <li class="layuimini-tab-roll-right layui-icon layui-icon-right"></li>
                <li class="layui-tab-tool layui-icon layui-icon-down">
                    <ul class="layui-nav close-box">
                        <li class="layui-nav-item">
                            <a href="javascript:;"><span class="layui-nav-more"></span></a>
                            <dl class="layui-nav-child">
                                <dd><a href="javascript:;" layuimini-tab-close="current">关 闭 当 前</a></dd>
                                <dd><a href="javascript:;" layuimini-tab-close="other">关 闭 其 他</a></dd>
                                <dd><a href="javascript:;" layuimini-tab-close="all">关 闭 全 部</a></dd>
                            </dl>
                        </li>
                    </ul>
                </li>
            </div>
            <div class="layui-tab-content">
                <div id="layuiminiHomeTabIframe" class="layui-tab-item layui-show"></div>
            </div>
        </div>
    </div>
</div>

<script src="/plugin/layuimini-v2/lib/layui-v2.6.3/layui.js" charset="utf-8"></script>
<!-- <script src="/plugin/layuimini-v2/js/lay-config.js?v=2.0.0" charset="utf-8"</script> -->
<script src="/js/common.js" charset="uft-8"></script>
<script src="/js/lib/Tab.js" charset="utf-8"></script><!-- 这里是导入自己写的js啦。不过内容就是将layuimini提供的内荣拿下来改改,其实可以自己跟着写的 -->
</body>
</html>

js部分:

 layui.use(['jquery', 'layer'], function () {
        var $ = layui.jquery,
            layer = layui.layer;

        /**
             * 菜单模块切换
             */
            $('body').on('click', '[data-menu]', function () {
                var loading = layer.load(0, {shade: false, time: 2 * 1000});
                var menuId = $(this).attr('data-menu');
                // header
                $(".layuimini-header-menu .layui-nav-item.layui-this").removeClass('layui-this');
                $(this).addClass('layui-this');
                // left
                $(".layuimini-menu-left .layui-nav.layui-nav-tree").addClass('layui-hide');
                $(".layuimini-menu-left .layui-nav.layui-nav-tree.layui-hide").removeClass('layui-this');
                $("#" + menuId).removeClass('layui-hide');
                $("#" + menuId).addClass('layui-this');
                layer.close(loading);
            });

            /**
             * 菜单缩放
             */
            $('body').on('click', '.layuimini-site-mobile', function () {
                var loading = layer.load(0, {shade: false, time: 1 * 10});
                var isShow = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
                if (isShow == 1) { // 缩放
                    $('.layuimini-tool [data-side-fold]').attr('data-side-fold', 0);
                    $('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-indent');
                    $('.layui-layout-body').removeClass('layuimini-all');
                    $('.layui-layout-body').addClass('layuimini-mini');
                } else { // 正常
                    $('.layuimini-tool [data-side-fold]').attr('data-side-fold', 1);
                    $('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-outdent');
                    $('.layui-layout-body').removeClass('layuimini-mini');
                    $('.layui-layout-body').addClass('layuimini-all');
                    layer.close(window.openTips);
                }
                element.init();
                layer.close(loading);
            });
            /**
             * 菜单缩放
             */
            $('body').on('click', '[data-side-fold]', function () {
                var loading = layer.load(0, {shade: false, time: 1 * 10});
                var isShow = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
                if (isShow == 1) { // 缩放
                    $('.layuimini-tool [data-side-fold]').attr('data-side-fold', 0);
                    $('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-indent');
                    $('.layui-layout-body').removeClass('layuimini-all');
                    $('.layui-layout-body').addClass('layuimini-mini');
                    // $(".menu-li").each(function (idx,el) {
                    //     $(el).addClass("hidden-sub-menu");
                    // });

                } else { // 正常
                    $('.layuimini-tool [data-side-fold]').attr('data-side-fold', 1);
                    $('.layuimini-tool [data-side-fold]').attr('class', 'fa fa-outdent');
                    $('.layui-layout-body').removeClass('layuimini-mini');
                    $('.layui-layout-body').addClass('layuimini-all');
                    // $(".menu-li").each(function (idx,el) {
                    //     $(el).removeClass("hidden-sub-menu");
                    // });
                    layer.close(window.openTips);
                }
                element.init();
                layer.close(loading);
            });

            /**
             * 手机端点开模块
             */
            $('body').on('click', '.layuimini-header-menu.layuimini-mobile-show dd', function () {
                var loading = layer.load(0, {shade: false, time: 2 * 1000});
                var check = $('.layuimini-tool [data-side-fold]').attr('data-side-fold');
                if(check === "1"){
                    $('.layuimini-site-mobile').trigger("click");
                    element.init();
                }
                layer.close(loading);
            });
    });


然后就会形成大家看到页面效果:

 

 

2.LAYUImini制作导航栏和菜单栏(LAYUIMINI文档是有案例可以参考的)

        官方写菜单接口的案例,亲测是可用的:点击这里查看即可

        本着简单就可的原则,我是不希望所有的东西都要自己写js,真的很累,直接在后端传所有数据到前端即可。我在测试官方文档给我的案例后,改改代码就可以用了,看这里

 框框中的方法如下,你直接黏贴使用即可。

 function getProjectUrl() { /* 获取你的访问地址前缀 */
            var layuiDir = layui.cache.dir;
            if (!layuiDir) {
                var js = document.scripts, last = js.length - 1, src;
                for (var i = last; i > 0; i--) {
                    if (js[i].readyState === 'interactive') {
                        src = js[i].src;
                        break;
                    }
                }
                var jsPath = src || js[last].src;
                layuiDir = jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
            }
            return layuiDir.substring(0, layuiDir.indexOf('assets'));
        }

然后就会得到一下的结果:

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐