通用后台管理系统UI模板-AdminLTE简介及构造动态菜单栏

AdminLTE是一款基于bootstrap的后台管理系统的通用模板UI,它的样式美观且较为符合大多数后台管理系统的需求,典型的上|左右|下的布局形式。而且提供了一整套咱们开发的时候可能用到的UI样式,好比表格,表单,图表,日历等。很是适合像我这样对样式编排不太擅长的后端开发者。有了它,咱们能够不用本身去写不少复杂的html,css。而把更多时间和精力留在后台的开发上。css

话很少说,接下来我简要的介绍一下这款模板UI框架的用法。html

官网:https://adminlte.io/前端

该款框架是免费的,能够直接在官网下载,下载下来的文件大概有50多兆,包含了全部的html,css,js,还有不少的demo。可供咱们随时查阅学习。jquery

先来看看总体的UI的风格吧,是否是挺炫酷的。web

能够说几乎全部的后台须要用到的样式均可以从中寻找获得。ajax

因为全套的UI都是静态数据,因此本篇文章着重介绍一下如何动态构造左侧的菜单栏。这应该也是你们比较关心的问题。redis

所谓的动态就是指的是从数据库或者文件,或者内存中取到的数据。数据库

本人习惯将菜单的数据写成一个静态的js文件,放在项目的js目录中,这样作的好处是没必要每次都去从数据库请求,减小IO操做形成的性能和时间损失,固然你也能够从数据库去请求,甚至把菜单数据放入到redis等内存数据库。各种方法都不影响咱们前端代码的编写,由于传递的数据格式都是json.json

1.将菜单数据写入一个json文件,代码以下。该文件的路径为webapp/static/json/menu.json。bootstrap

[{
"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 }
相关文章
相关标签/搜索