SSM整合之企業級後臺管理系統(11) - 實現主頁中的頂部菜單和左側菜單

前面的教程和大家一起學習了系統登錄部分的開發,登錄之後呢我們需要展示管理平臺的主頁,通常,管理系統的主頁是這樣佈局的:

  • 頂部:基本包括系統名稱、主功能菜單、用戶名稱和頭像
  • 中間部分:左側是主功能菜單下的子菜單,右側是子菜單對應的頁面
  • 底部:  技術支持信息,也就是開發者給自己打的廣告😄

上面說的這種佈局模式其實就是邊界佈局(Border Layout)。也就是,下面截圖這個樣子:

接下來,我們就一起來學習一下如何實現主頁中的頂部和左側菜單吧

一、菜單欄效果演示

菜單部分最終的效果是,點擊頂部菜單,相應的子菜單會在左側加載出來;點擊左側的菜單,正文部分會加載該部分頁面。無圖言卵,頂部菜單和左側菜單欄的實現後效果:

二、實現頂部菜單(一級菜單)

在介紹代碼實現之前,我們先來思考一下頂部菜單實現的原理。

首先,我們頁面中加上一個<ul>用來展示菜單內容,在index頁面加載時調用initTopMenu()函數初始化該<ul>。那菜單的內容從哪裏來呢?頁面上寫死嗎?當然不行啦,不用的用戶登錄進來需要顯示不同的菜單,所以,我們需要從後臺返回當前登錄用戶的菜單選項。當我們點擊頂部菜單時,switchMenu()函數響應點擊事件並加載該菜單的子菜單到頁面左側。

1、index.jsp中<body>元素中加上<header>,header中包含了一個id爲"nav-left"的<ul>用來展示頂部菜單:

<header>
    <nav class="navbar navbar-default navbar-fixed-top">
        <a href="javascript:void(0);" class="navbar-brand" id="navbar-brand">OMS System </a>
        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav" id="nav-left"> </ul>
            <ul class="nav navbar-nav navbar-right" id="nav-right" style="height: 100%">
                <li style="padding-top:5px;"><a href="javascript:void(0);" style="vertical-align: middle;display:inline;padding-left:3px;">&nbsp;${user_cname}, 歡迎登錄</a></li>
            </ul>
        </div>
    </nav>
</header>

2、加載index頁面時,初始化頂部菜單:

//初始化頂部菜單
function initTopMenu(topMenuList) {
    if (topMenuList == '' || topMenuList == undefined) {
        alert('系統初始化失敗,請聯繫管理員');
    }
    var topMenus = JSON.parse(topMenuList);
    for (let i = 0; i < topMenus.length; i++) {
        let topMenu = topMenus[i];
        let m_id = topMenu.m_id;
        let m_name = topMenu.m_name;
        let m_icon = topMenu.m_icon;
        let liClass = '';
        if (i == 0) {
            liClass = 'class="newactive"';
            //保存第一個菜單的id,用戶加載左側菜單
            window.sessionStorage.setItem('first_module_id', m_id);
        }
        $('#nav-left').append('<li '+liClass+'><a href="javascript:void(0)" onclick="switchMenu(this)" data-mid="'+m_id+'"><i class="' + m_icon + '"></i> '+ m_name +'</a></li>')
     }
}

3、加載index頁面時調用的controller,在該controller中返回頂部菜單和左側菜單內容

@RequestMapping("/index")
public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
    ModelAndView model = new ModelAndView(INDEX_PAGE);
    String username = request.getSession().getAttribute("username").toString();
    //根據用戶名獲取菜單
    List<UserRoleModule> menuList = userRoleModuleService.getMenuByUsername(username);
    List<UserRoleModule> topMenuList = new ArrayList<UserRoleModule>();
    List<UserRoleModule> sideMenuList = new ArrayList<UserRoleModule>();
    //分別保存頂部菜單和左側菜單
    for (UserRoleModule menu : menuList) {
        if ("0".equals(menu.getM_parent().toString())) {
           topMenuList.add(menu);
        } else {
           sideMenuList.add(menu);
        }
    }
    if (menuList.size() > 0) {
        model.addObject("user_cname", menuList.get(0).getCname());
    } else {
        model.addObject("user_cname", username);
    }
    String topMenus = JSON.toJSONString(topMenuList);
    String sideMenus = JSON.toJSONString(sideMenuList);
    model.addObject("topMenuList", topMenus);
    model.addObject("page", "index.jsp page's value");
    model.addObject("current_user", username);
    return model;
}

三、實現左側菜單(二級菜單)

index頁面加載時,左側菜單內容也由後臺返回,並且由initSideMenu()函數將菜單在頁面中顯示出來;當點擊頂部菜單時,switchMenu()函數將對應的二級菜單展示出來。

左側菜單頁面<ul>元素

<aside class="main-sidebar">
    <section class="sidebar">
        <ul id="sidebar-menu" class="sidebar-menu" data-widget="tree">
    </section>
<aside>

initSideMenu()函數

//初始化左側菜單
function initSideMenu(sideMenuList, topMenuSelected) {
    if (sideMenuList == '' || sideMenuList == undefined) {
        alert('系統初始化失敗,請聯繫管理員');
    }
    var sideMenus = JSON.parse(sideMenuList);
    var htmlContent = '';
    let index = 0;//用於控制第一個菜單爲展開狀態,其他則爲收起狀態
    for (let i = 0; i < sideMenus.length; i++) {
        let sideMenu = sideMenus[i];
        if (sideMenu.m_parent + '' == topMenuSelected+'') {
           index ++;
           htmlContent += '<li class="treeview ';
           if (index == 1) {
              htmlContent += 'active menu-open">';
           } else {
               htmlContent += '">';
           }
           htmlContent += '<a href="javascript:void(0);"><i class="'+sideMenu.m_icon+'"></i><span><strong>&nbsp;'+sideMenu.m_name+'</strong></span>'+'<span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a>';
           htmlContent += '<ul class="treeview-menu">';
           for (let j = 0; j < sideMenus.length; j++) {
               if (sideMenu.m_id == sideMenus[j].m_parent) {
                   htmlContent += '<li><a href="javascript:void(0)" onclick="chooseMenu(this)" class="myLeftMenu" data="<%=basePath%>'+sideMenus[j].url+'"><i class="'+sideMenus[j].m_icon+'"></i>&nbsp;&nbsp;'+sideMenus[j].m_name+'</a></li>';
               }
            }
            htmlContent += '</ul></li>';
        }
    }
    $('#sidebar-menu').empty();
    $('#sidebar-menu').append(htmlContent);
}

四、菜單聯動

使用switchMenu()函數來聯動菜單

//點擊頂部菜單,切換左側菜單
function switchMenu(e) {
    //修改點擊後樣式
    var parentClass = $(e).parent().attr('class');
    if (parentClass != '' && parentClass != undefined && parentClass.indexOf('newactive') > -1) {
        return;
    }
    var bros = $(e).parent().parent().children();
    for (let i = 0; i < bros.length; i++) {
        let bro = bros[i];
        $(bro).removeClass('newactive');
    }
    var parent = $(e).parent();
    $(parent).addClass('newactive');
    //切換左側菜單
    var parent_id = $(e).attr('data-mid');
    var sideMenuList = '${sideMenuList}';
    initSideMenu(sideMenuList, parent_id);
}

五、本篇結束語

一級菜單和二級菜單的實現原理並不複雜,總結一下就是:

  1. 後臺從數據庫查詢當前登錄用戶的菜單,返回一級菜單和二級菜單內容到前端
  2. 頁面加載時就初始化解析一級和二級菜單,並渲染到頁面中
  3. 當點擊一級菜單時,重新渲染二級菜單

當然,實現起來還是有很多細節需要考慮;並且,要想菜單看起來好看點,還需要很多CSS樣式的點綴,在上文博客中並非一應俱全,需要獲取更多源碼的同學歡迎加羣呀:584017112

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章