通用后台管理系統UI模板-AdminLTE簡介及構造動態菜單欄


AdminLTE是一款基於bootstrap的后台管理系統的通用模板UI,它的樣式美觀且較為符合大多數后台管理系統的需求,典型的上|左右|下的布局形式。並且提供了一整套我們開發的時候可能用到的UI樣式,比如表格,表單,圖表,日歷等。非常適合像我這樣對樣式編排不太擅長的后端開發者。有了它,我們可以不用自己去寫很多復雜的html,css。而把更多時間和精力留在后台的開發上。

話不多說,接下來我簡要的介紹一下這款模板UI框架的用法。

官網:https://adminlte.io/

該款框架是免費的,可以直接在官網下載,下載下來的文件大概有50多兆,包含了所有的html,css,js,還有很多的demo。可供我們隨時查閱學習。

先來看看整體的UI的風格吧,是不是挺炫酷的。

可以說幾乎所有的后台需要用到的樣式都可以從中尋找得到。

由於全套的UI都是靜態數據,所以本篇文章着重介紹一下如何動態構造左側的菜單欄。這應該也是大家比較關心的問題。

所謂的動態就是指的是從數據庫或者文件,或者內存中取到的數據。

本人習慣將菜單的數據寫成一個靜態的js文件,放在項目的js目錄中,這樣做的好處是不必每次都去從數據庫請求,減少IO操作造成的性能和時間損失,當然你也可以從數據庫去請求,甚至把菜單數據放入到redis等內存數據庫。各類方法都不影響我們前端代碼的編寫,因為傳遞的數據格式都是json.

1.將菜單數據寫入一個json文件,代碼如下。該文件的路徑為webapp/static/json/menu.json。

[{
"menuId":"1",
"name": "基本信息",
"controller":"#",
"child": []
},{
"menuId":"2",
"name": "會員管理",
"controller":"#",
"child": [{
"menuId":"3",
"pMenuId":"2",
"name": "會員概覽",
"controller":"user/home"
},{
"menuId":"4",
"pMenuId":"2",
"name": "添加會員",
"controller":"user/add"
}]
},{
"menuId":"5",
"name": "銷售管理",
"controller":"#",
"child": [{
"menuId":"5",
"pMenuId":"6",
"name": "銷售返佣",
"controller":"post/home"
},{
"menuId":"5",
"pMenuId":"7",
"name": "銷售報表",
"controller":"post/add"
}]
}]

至於如何寫入到文件,我們可以在每次修改菜單以后,先獲取菜單的json數據,然后調用如下代碼來將菜單的json數據寫入文件。

    public void generateMenuJson(String jsonStr) {
        try {
            File f = new File(ServletActionContext.getServletContext()
                    .getRealPath("/static/json") + "/menu.json");
            if (!f.exists()) {
                f.createNewFile();
            }
            // 定義編碼
            OutputStreamWriter write = new OutputStreamWriter(
                    new FileOutputStream(f), "UTF-8");
            BufferedWriter writer = new BufferedWriter(write);
            writer.write(jsonStr);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.前台ajax獲取json數據,並且動態構造出html元素及樣式。

主要是用了jQuery ajax異步獲取數據,還有就是jquery的append()方法,代碼沒有什么高深的,只是拼接的時候要很認真。一個取巧的方法是去下載下來的html源碼中復制一些關鍵的代碼,避免寫錯。

 1 $(function () {
 2     $.ajax({
 3         type: 'get',
 4         url:'static/json/menu.json',
 5         dataType:'json',
 6         success:function(data){
 7             var menu=null;
 8             var html=null;
 9             var childLen=null;
10             var child=null;
11             var json=data;
12             console.log(json);
13             for(var i in json){
14                 menu=json[i];
15                 //這里默認展開第一個主菜單
16                 if(i==0){
17                     html=$('<li menu-id="'+i+'" class="active treeview "><li>');
18                 }else{
19                     html=$('<li menu-id="'+i+'" class="treeview "><li>');
20                 }
21                 $(".sidebar .sidebar-menu").append(html);
22                 html=$('<a href="'+menu.controller+'"><i class="fa fa-dashboard"></i> <span>'+menu.name+'</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a><ul menuUL-id="'+i+'" class="treeview-menu"></ul>');
23                 $('[menu-id="'+i+'"]').append(html);
24                 //繼續遍歷二級菜單
25                 childLen=menu.child.length;
26                 for(var j in menu.child){
27                     child=menu.child[j];
28                     //這里默認設置第一個子菜單為選中狀態
29                     if(j==0){
30                             html=$('<li class="active"><a href="'+child.controller+'"><i class="fa fa-circle-o"></i>'+child.name+'</a></li>');
31                     }else{
32                             html=$('<li><a href="'+child.controller+'"><i class="fa fa-circle-o"></i>'+child.name+'</a></li>');
33                     }            
34                     $('[menuUL-id="'+i+'"]').append(html);
35                 }
36             }
37         }
38     
39 });
40 });

相信大家對照demo中的html源碼,可以很容易的理解上述代碼。我們把原來的左側菜單的靜態html注釋掉,引入上述的js文件。看看效果。

這樣基本實現了菜單顯示的效果。但是還有一個缺點,就是菜單不能根據頁面動態變換樣式,比如我們在會員概覽頁面,此時展開的是會員管理,選中的是會員概覽。而當我們到了銷售管理的時候,我們又希望此時菜單能展開銷售管理主菜單並選中相應的子菜單。

要實現這個功能,我們需要在上述的js代碼中傳入當前訪問的鏈接的菜單id,以及其父級菜單id(如果是最上層的菜單,則其父菜單為自己)。然后根據這兩個參數來進行菜單是否展開即是否選中的判斷。具體步驟如下。

1.菜單實體如下

package com.wonyen.entity;

public class TMenu {
    private int menuId;//菜單編號
    private int pMenuId;//父菜單編號
    private String name;//菜單名稱
    private String controller;//菜單對應的controller
    public int getMenuId() {
        return menuId;
    }
    public void setMenuId(int menuId) {
        this.menuId = menuId;
    }
public int getpMenuId() { return pMenuId; } public void setpMenuId(int pMenuId) { this.pMenuId = pMenuId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getController() { return controller; } public void setController(String controller) { this.controller = controller; } }

2.獲取當前菜單對象,並傳入到前台。以會員概覽頁面為例,代碼如下。第8行獲取了當前的菜單對象,第9行將其傳入到ModelAndView對象中,我們就可以在轉發的jsp頁面中拿到這個menu對象了。

 1     @RequestMapping("partnerHome")
 2     public ModelAndView partnerHome(ParamModel pm) {
 3         ModelAndView mv = new ModelAndView("back/partner/PartnerList");
 4         mv.addObject("pm", pm);
 5         List<TPartnerLevel> partnerLevelList = partnerLevelService
 6                 .getPartnerLevelList();
 7         mv.addObject("partnerLevelList", partnerLevelList);
 8         TMenu menu=menuService.getMenuByController("partnerHome");//獲取當前的菜單信息
 9         mv.addObject("menu", menu);
10         return mv;
11     }

3.在每個頁面body加入兩個屬性,menu_id和p_menu_id.如下所示。

<body class="hold-transition skin-red sidebar-mini" menu_id="${menu.menuId}" p_menu_id="${menu.pMenuId}">

4.重新改寫原來js代碼,讓其支持根據當前頁面來變換選中的菜單。

$(function () {
    var menu_id=$('body').attr('menu_id');//菜單id
    var p_menu_id=$('body').attr('p_menu_id');//父級菜單id
    $.ajax({
        type: 'get',
        url:'static/json/menu.json',
        dataType:'json',
        success:function(data){
            var menu=null;
            var html=null;
            var childLen=null;
            var child=null;
            var json=data;
            console.log(json);
            for(var i in json){
                menu=json[i];
                //如果父菜單是該菜單,就展開
                if(menu.menuId==p_menu_id){
                    html=$('<li menu-id="'+i+'" class="active treeview "><li>');
                }else{
                    html=$('<li menu-id="'+i+'" class="treeview "><li>');
                }
                $(".sidebar .sidebar-menu").append(html);
                html=$('<a href="'+menu.controller+'"><i class="fa fa-dashboard"></i> <span>'+menu.name+'</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a><ul menuUL-id="'+i+'" class="treeview-menu"></ul>');
                $('[menu-id="'+i+'"]').append(html);
                //繼續遍歷二級菜單
                childLen=menu.child.length;
                for(var j in menu.child){
                    child=menu.child[j];
                    //如果子菜單是該菜單,則設為active選中
                    if(child.menuId==menu_id){
                            html=$('<li class="active"><a href="'+child.controller+'"><i class="fa fa-circle-o"></i>'+child.name+'</a></li>');
                    }else{
                            html=$('<li><a href="'+child.controller+'"><i class="fa fa-circle-o"></i>'+child.name+'</a></li>');
                    }            
                    $('[menuUL-id="'+i+'"]').append(html);
                }
            }
        }
    
});
});

經過上述步驟以后,我們就可以得到更為合理的左側菜單了。來看看效果吧。

--會員概覽頁

---會員添加頁

看,已經實現了我們想要的效果。如果你也正在尋找一個后台的UI,趕緊試試吧。

-----------------------------------------------------------------------------------------------2018年4月2日更新-------------------------------------------------------------------------------------------------------------------------------------------------------------------

最近發現一種新的記錄菜單選中情況的方法,就是利用瀏覽器的緩存,每次點擊菜單的時候,將點擊的菜單Id記錄到瀏覽器緩存中,然后加載菜單的時候通過緩存中的菜單來比對,匹配成功就將其展開並且設為active.這種方法就不需要在服務端傳入當前的菜單了,簡單了很多。

 1 $(function () {
 2     var firstLvId=getFirstLvMenu();//一級菜單
 3     var secondLvId=getSecondLvMenu();//二級菜單
 4     var thirdLvId=getThirdLvMenu();//三級菜單
 5     $.ajax({
 6         type: 'get',
 7         url:'/menu/tree',
 8         dataType:'json',
 9         success:function(data){
10             var menu=null;
11             var html=null;
12             var childLen=null;
13             var child=null;
14             var json=data;
15             console.log(json);
16             for(var i in json){
17                 menu=json[i];
18                 //如果父菜單是該菜單,就展開
19                 if(menu.menuId==firstLvId){
20                     html=$('<li menu-id="'+i+'" class="active treeview "><li>');
21                 }else{
22                     html=$('<li menu-id="'+i+'" class="treeview "><li>');
23                 }
24                 $(".sidebar .sidebar-menu").append(html);
25                 html=$('<a class="first-menu" href="../'+menu.menuSrc+'" onclick="saveFirstLvMenu('+menu.menuId+')"><i class="fa fa-dashboard"></i> <span>'+menu.menuName+'</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a><ul menuUL-id="'+i+'" class="treeview-menu"></ul>');
26                 $('[menu-id="'+i+'"]').append(html);
27                 //繼續遍歷二級菜單
28                 childLen=menu.child.length;
29                 for(var j in menu.child){
30                     child=menu.child[j];
31                     //如果子菜單是該菜單,則設為active選中
32                     if(child.menuId==secondLvId){
33                             html=$('<li class="active"><a class="second-menu" href="../'+child.menuSrc+'" onclick="saveSecondLvMenu('+child.menuId+')"><i class="fa fa-circle-o"></i>'+child.menuName+'</a></li>');
34                     }else{
35                             html=$('<li><a class="second-menu" href="../'+child.menuSrc+'" onclick="saveSecondLvMenu('+child.menuId+')"><i class="fa fa-circle-o"></i>'+child.menuName+'</a></li>');
36                     }            
37                     $('[menuUL-id="'+i+'"]').append(html);
38                 }
39             }
40         }
41     
42 });
43 });
44 function saveFirstLvMenu(menuId) {
45     var id = JSON.stringify(menuId);
46      window.sessionStorage.setItem("firstMenuId", id);
47 }
48 
49 function saveSecondLvMenu(menuId) {
50     var id = JSON.stringify(menuId);
51      window.sessionStorage.setItem("secondMenuId", id);
52 }
53 
54 function saveThirdLvMenu(menuId) {
55     var id = JSON.stringify(menuId);
56      window.sessionStorage.setItem("thirdMenuId", id);
57 }
58 
59 function getFirstLvMenu() {
60     return JSON.parse(window.sessionStorage.getItem("firstMenuId"));
61 }
62 function getSecondLvMenu() {
63     return JSON.parse(window.sessionStorage.getItem("secondMenuId"));
64 }
65 function getThirdLvMenu() {
66     return JSON.parse(window.sessionStorage.getItem("thirdMenuId"));
67 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM