• 第二节:前端规范封装设计和基于EasyUI前端基础菜单框架的搭建(Layout、Tab、Tree)


    一. 前端规范设计

    1. 页面JS

     这里主要采用三个对象来处理页面的各种业务,mainUtil用于处理各种初始化,pageUtils用于页面增、删、改 等等方法的封装,otherUtil用于封装一下帮助方法。

    格式如下:

    (function(w){
        //全局变量
        
        //一. 各种初始化
        var mainUtil={
            init:function(){            
            },
            initBasic:function(){      
            },
            initTapEvent:function(){      
            }
        };    
        //二. 封装各种方法
        var pageUtil={
            xxx:function(){            
            }
        };    
        //三. 其他
        var otherUtil={
            xxx:function(){            
            }
        };        
        //对外公开
        w.mainUtil=mainUtil;
        w.otherUtil=otherUtil;    
    })(window);
    
    //页面加载
    $(function () {
        mainUtil.init();
    });

    2. 公共JS封装

     这里封装myUtils.js文件,将公共的方法进行剥离,方便每个页面进行调用。包括ajax封装、localstorage缓存的增删改查、EasyUI各种提示框封装、Form表单内容序列化等等。

    代码分享:

    //帮助类
    //暂定需要封装:缓存、ajax对应jwt校验错误、时间转换 、样式切换 
    
    var myUtils = {
        //1.ajax请求
        ajax: function(type, url, data, funSuc, funErr) {
            $.ajax({
                type: type,
                url: url,
                beforeSend: function(xhr) {
                    xhr.setRequestHeader("X-Requested-With", 'XMLHttpRequest');
                    xhr.setRequestHeader("auth", myUtils.localGet('token'));
                },
                cache: false,
                dataType: 'JSON',
                data: data,
                success: function(data) {
                    funSuc(data);
                },
                timeout: 6000,
                //当安全校验未通过的时候进入这里
                error: function(xhr) {
                    if (typeof funErr == "function") {
                        funErr(xhr); //用于需要手动写回调
                    }
                    if (xhr.status == 401) {
                        var errorMsg = xhr.responseText;
                        console.log(errorMsg);
                        //目前401统一退回登录页,暂未处理自动刷新机制
                        myUtils.alertMsg(errorMsg, "提示", function() {
                            //以下地址在生产环境中需要统一改为:"/loginIndex.html?Msg=" + errorMsg;
                            if (window != top) {
                                top.location.href = "/01-EasyUISolution/loginIndex.html?Msg=" + errorMsg;
                            } else {
                                window.location.href = "loginIndex.html?Msg=" + errorMsg;
                            }
                        });
                    }
                }
            })
        },
        //2. 初始化主题样式
        initTheme: function(url) {
            //获取主题
            var theme = myUtils.localGet("theme");
            if (!theme) {
                theme = "coolblacklight";
            }
            //新版本的【动态加载主题】
            if (url == "" || url == undefined) {
                $("#j_theme").attr("href", "../../../css/themes/skin-" + theme + ".css");
            } else {
                $("#j_theme").attr("href", url + theme + ".css");
            }
        },
        //3. 缓存框架
        //新增
        localSet: function(key, val) {
            window.localStorage.setItem(key, val);
        },
        //查询
        localGet: function(key) {
            return window.localStorage.getItem(key);
        },
        //删除
        localRemove: function(key) {
            window.localStorage.removeItem(key);
        },
        //全部删除
        localClear: function() {
            window.localStorage.clear();
        },
        //5.各种弹框
        //弹框
        alertMsg: function(msg, title, funcSuc) {
            if ($.messager) {
                $.messager.alert(title, msg, "info", function() {
                    if (funcSuc) {
                        funcSuc();
                    }
                })
            } else {
                alert(title + "
     " + msg);
                if (funcSuc) {
                    funcSuc();
                }
            }
        },
        //dialog: div以easyui对话框形式显示出来
        dialog: function(options) {
            var opts = $.extend({
                modal: true,
                onClose: function() {
                    $(this).dialog('destroy');
                }
            }, options);
            return $('<div/>').dialog(opts);
        },
        // 操作信息提示确认框Confirm
        messagerConfirm: function(title, msg, fn) {
            return $.messager.confirm(title, msg, fn);
        },
        //操作信息提示alert
        messagerAlert: function(title, msg, icon, fn) {
            return $.messager.alert(title, msg, icon, fn);
        },
        //操作信息提示Show
        messagerShow: function(options) {
            return $.messager.show(options);
        },
        //6.把表单元素序列化成对象
        serializeObject: function(form) {
            var o = {};
            $.each(form.serializeArray(), function(intdex) {
                if (o[this['name']]) {
                    o[this['name']] = o[this['name']] + "," + this['value'];
                } else {
                    o[this['name']] = this['value']
                }
            });
            return o;
        },
        //7. 格式化字符串
        fs: function(str) {
            for (var i = 0; i < arguments.length - 1; i++) {
                str = str.replace("{" + i + "}", arguments[i + 1]);
            }
            return str;
        },
        //8. 把一个以逗号分割的字符串,返回List,List里每一项都是一个字符串
        getList: function(value) {
            if (value != undefined && value != '') {
                var values = [];
                var t = value.split(',');
                for (var i = 0; i < t.length; i++) {
                    values.push('' + t[i]);
                }
                return values;
            } else {
                return [];
            }
        },
        //9. 去掉提示框右上角×号
        removeXMark: function() {
            $(".window.messager-window .window-header .panel-tool").html("");
        }
    };
    View Code

    特别注意这里的ajax封装,当error报错的时候,调用的时候可以什么不写,走封装内的回调,也可以写function(){} ,自定义回调。

    3. 页面资源引入

     按照先CSS,后JS的顺序进行引入。

    (1). CSS:先引入easyui.css→主题样式→自定义样式→图标样式

    (2). JS:JQuery→easyui.js→easyui中文包→自定义js

    代码分享: 

            <!--EasyUI 样式-->
            <link href="css/themes/base/easyui.css" rel="stylesheet" />
            <!-- 直接引用默认主题,下面通过jQuery动态替换主题的href -->
            <link href="css/themes/skin-coolblacklight.css" rel="stylesheet" id="j_theme" />
            <link href="css/site.css" rel="stylesheet" />
            <link href="css/fontawesome/css/font-awesome.min.css" rel="stylesheet" />
            <!--Jquery文件-->
            <script src="js/easyui/jquery.min.js" type="text/javascript" charset="utf-8"></script>
            <!--EasyUI js文件-->
            <script src="js/easyui/jquery.easyui.min.js" type="text/javascript" charset="utf-8"></script>
            <script src="js/easyui/easyui-lang-zh-CN.js" type="text/javascript" charset="utf-8"></script>
            <!--自定义库-->
            <script src="js/utils/urlConfig.js" type="text/javascript" charset="utf-8"></script>
            <script src="js/utils/myUtils.js" type="text/javascript" charset="utf-8"></script>

    二. 主页面搭建

    1. Layout页面布局

      布局容器有5个区域:北、南、东、西和中间。中间区域面板是必须的,边缘的面板都是可选的。每个边缘区域面板都可以通过拖拽其边框改变大小,也可以点击折叠按钮将面板折叠起来。布局可以进行嵌套,用户可以通过组合布局构建复杂的布局结构。

      该框架仅采用北、西、中 三个区域即可。 

    2. Tab选项卡创建与关闭 

    (1). 创建

    要借助iframe标签显示

                      addTab: function(subtitle, url, icon) {
                            if (!$("#mainTab").tabs('exists', subtitle)) {
                                var closableFlag = true;
                                if (subtitle == "我的桌面") {
                                    closableFlag = false;
                                }
                                $("#mainTab").tabs('add', {
                                    title: subtitle,
                                    content: '<iframe frameborder="0" src="' + url +
                                        '" scrolling="auto" style="100%; height:100%;overflow:hidden"></iframe>',
                                    closable: closableFlag,
                                    icon: icon
                                });
                            } else {
                                $("#mainTab").tabs('select', subtitle);
                                $("#tab_menu-tabrefresh").trigger("click");
                            }
                        },

     调用:

    var url = "view/Main_Areas/MyDeskTop.html";
    otherUtil.addTab("我的桌面", url, "fa fa-home");

    (2). 关闭

    $('#mainTab').tabs('close', currtab_title);

    3. Tree+Accordion菜单导航

     这里的实现思路是每个模块对应1个Accordion,创建Accordion的时候,content是一个承载tree的标签。

    (1). 接口

     递归获取数据,最终组成1个List。

    代码分享:

       /// <summary>
            /// 获取权限信息
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public async Task<string> GetEasyLeftMenu()
            {
                try
                {
                    var jwtData = JsonHelp.ToObject<JwtData>(ControllerContext.RouteData.Values["auth"].ToString());
                    var userId = jwtData.userId;
    
                    //根据用户Id,查出来所有的角色,然后把所有角色对应的权限id查出来并去重
                    var data1 = _baseService.Entities<T_SysUserRole>();
                    var data2 = _baseService.Entities<T_SysRolePer>();
                    var data = await (from a in data1
                                      join b in data2 on a.roleId equals b.roleId
                                      where a.userId == userId
                                      select b).Select(p => p.perId).Distinct().ToListAsync();
    
                    //根据权限Id组装固定格式的权限信息进行反馈
                    var perList = await _baseService.GetListByAsync<T_SysPermisson>(u => u.delFlag == 0 && data.Contains(u.id));
    
                    List<EasyUiMenuInfor> menuList = GetOwnAllPer(perList, "1");
                    return JsonHelp.ToJsonString(menuList);
                }
                catch (Exception ex)
                {
                    LogUtils.Error(ex);
                    return "";
                }
            }
    
    
            /// <summary>
            /// 获取所有自己的菜单信息
            /// </summary>
            /// <param name="perList">所有的自己的菜单权限</param>
            /// <param name="parentId">父菜单id</param>
            /// <returns></returns>
            public List<EasyUiMenuInfor> GetOwnAllPer(List<T_SysPermisson> perList, string parentId)
            {
                var perListMain = perList.Where(p => p.parentId == parentId).OrderBy(u => u.sortFlag).ToList();
                if (perListMain.Count() > 0)
                {
                    //最新的组装形式
                    List<EasyUiMenuInfor> menuList = new List<EasyUiMenuInfor>();
                    foreach (var item in perListMain)
                    {
                        EasyUiMenuInfor menuItem = new EasyUiMenuInfor();
                        menuItem.id = item.id;
                        menuItem.text = item.menuName;
                        var myUrl = item.frontUrl;
                        menuItem.attributes = myUrl;
                        menuItem.iconCls = item.iconClassName;
                        menuItem.children = GetChildPer(perList, item.id);
                        menuItem.state = menuItem.children.Count() == 0 ? "open" : "closed";
                        menuList.Add(menuItem);
                    }
                    return menuList;
                }
                else
                {
                    return new List<EasyUiMenuInfor>();  //返回空集合
                }
            }
    
    
            /// <summary>
            /// 获取所有的子菜单权限
            /// </summary>
            /// <param name="perList"></param>
            /// <param name="childId"></param>
            /// <returns></returns>
            public List<EasyUiMenuInfor> GetChildPer(List<T_SysPermisson> perList, string childId)
            {
                var perListMain = perList.Where(p => p.parentId == childId).OrderBy(u => u.sortFlag).ToList();
                if (perListMain.Count() > 0)
                {
                    return GetOwnAllPer(perList, childId);
                }
                else
                {
                    return new List<EasyUiMenuInfor>();  //返回空集合
                }
            }
    View Code

    (2). 前端js

     代码分享:

    var pageUtil = {
                        //1. 初始化菜单
                        initMenu: function() {
                            //仅保留手风琴左侧菜单
                            $("#RightAccordion").accordion({ //初始化accordion
                                fillSpace: true,
                                fit: true,
                                border: false,
                                animate: false
                            });
                            var parentId = "0";
                            pageUtil.loadAccordionMenu(parentId);
                            $("#RightAccordion ").parent().css("overflow", "hidden"); //外部隐藏
                        },
                        //2. 手风琴菜单组装
                        loadAccordionMenu: function(parentId) {
                            $(".topmenu").removeClass("selected");
                            $("#" + parentId).addClass("selected");
                            myUtils.ajax("post", GetEasyLeftMenuUrl, {}, function(data) {
                                //清空
                                var rcount = $('#RightAccordion .panel').length;
                                for (var i = 0; i < rcount; i++) {
                                    $('#RightAccordion').accordion("remove", 0);
                                }
                                var fristTitle;
                                if (data == "0") {
                                    return;
                                }
                                $.each(data, function(i, e) { //循环创建手风琴的项
                                    var id = e.id;
                                    $('#RightAccordion').accordion('add', {
                                        title: e.text,
                                        content: "<ul id='tree" + id + "'></ul>",
                                        selected: true,
                                        iconCls: e.iconCls
                                    });
                                    $("#tree" + id).tree({
                                        data: e.children,
                                        onClick: function(node) {
                                            if (node.state == 'closed') {
                                                $(this).tree('expand', node.target);
                                            } else if (node.state == 'open') {
                                                $(this).tree('collapse', node.target);
                                                if (node.children == undefined || node.children == null || node.children.length == 0) {
                                                    var tabTitle = node.text;
                                                    var url = node.attributes;
                                                    var icon = node.iconCls;
                                                    otherUtil.addTab(tabTitle, url, icon);
                                                }
                                            }
                                        }
                                    });
                                    $("#tree" + id + "").parent().css("overflow-y", "auto");
                                });
                                $('#RightAccordion').accordion('select', '系统设置'); //默认展开的选项卡名称
                            });
                        },
    }
    View Code

    三. 其它

    1. 设置主题 

     大致思路:EasyUI有个样式库,命名规则为:skin-xxx.css,如下图:

    (1). 每个页面引入一个默认样式,如:

    <link href="css/themes/skin-coolblacklight.css" rel="stylesheet" id="j_theme" />

    (2).  设置主题页面,选择对应的主题,存入缓存中(实质上就是存入了 skin- 后面的内容),并刷新页面。

    <div id="ModalStyle" class="easyui-dialog" style="600px;height:260px" data-options="iconCls:'',modal:true,closed:true">
                <table style="100%; padding:20px; line-height:30px;text-align:center;" id="j_test">
                    <tr>
                        <td>
                            <label for="coolblack"><img src="img/skin/skin-coolblack.png" style="60px;height:30px;" /></label><br /><input
                             id="coolblack" type="radio" name="themes" value="coolblack" />
                        </td>
                        <td>
                            <label for="red"><img src="img/skin/skin-red.png" style="60px;height:30px;" /></label><br /><input id="red"
                             type="radio" name="themes" value="red" />
                        </td>
                        <td>
                            <label for="green"><img src="img/skin/skin-green.png" style="60px;height:30px;" /></label><br /><input id="green"
                             type="radio" name="themes" value="green" />
                        </td>
                        <td>
                            <label for="purple"><img src="img/skin/skin-purple.png" style="60px;height:30px;" /></label><br /><input id="purple"
                             type="radio" name="themes" value="purple" />
                        </td>
                        <td>
                            <label for="blue"><img src="img/skin/skin-blue.png" style="60px;height:30px;" /></label><br /><input id="blue"
                             type="radio" name="themes" value="blue" />
                        </td>
                        <td>
                            <label for="yellow"><img src="img/skin/skin-yellow.png" style="60px;height:30px;" /></label><br /><input id="yellow"
                             type="radio" name="themes" value="yellow" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <label for="coolblacklight"><img src="img/skin/skin-coolblacklight.png" style="60px;height:30px;" /></label><br /><input
                             id="coolblacklight" type="radio" name="themes" value="coolblacklight" />
                        </td>
                        <td>
                            <label for="redlight"><img src="img/skin/skin-redlight.png" style="60px;height:30px;" /></label><br /><input
                             id="redlight" type="radio" name="themes" value="redlight" />
                        </td>
                        <td>
                            <label for="greenlight"><img src="img/skin/skin-greenlight.png" style="60px;height:30px;" /></label><br /><input
                             id="greenlight" type="radio" name="themes" value="greenlight" />
                        </td>
                        <td>
                            <label for="purplelight"><img src="img/skin/skin-purplelight.png" style="60px;height:30px;" /></label><br /><input
                             id="purplelight" type="radio" name="themes" value="purplelight" />
                        </td>
                        <td>
                            <label for="bluelight"><img src="img/skin/skin-bluelight.png" style="60px;height:30px;" /></label><br /><input
                             id="bluelight" type="radio" name="themes" value="bluelight" />
                        </td>
                        <td>
                            <label for="yellowlight"><img src="img/skin/skin-yellowlight.png" style="60px;height:30px;" /></label><br /><input
                             id="yellowlight" type="radio" name="themes" value="yellowlight" />
                        </td>
                    </tr>
                </table>
                <div class="endbtndiv">
                    <a id="btnReturn" href="javascript:$('#ModalStyle').dialog('close')" class="easyui-linkbutton btnc">取消</a>
                    <a id="btnSave" href="javascript:pageUtil.setThemes()" class="easyui-linkbutton btns">保存</a>
                </div>
            </div>
    View Code

     每次打开该页面的时候,从缓存中读取,如果没有则为默认样式,然后给下面弹框设置选中。 

    $("#SetThemes").click(function() {
                                //显示当前主题
                                var theme = myUtils.localGet("theme");
                                if (!theme) {
                                    theme = "coolblacklight";
                                }
                                $('#j_test').find("input[type='radio'][value='" + theme + "']").attr('checked', 'checked');
                                //打开弹框
                                $("#ModalStyle").dialog({
                                    title: '设置主题',
                                }).dialog('open');
                            });
    View Code

     效果图:

    (3). 然后每个页面都要初始化一下,从缓存中读取,然后替换 步骤1 中link引入的样式文件。

    方法封装

        //2. 初始化主题样式
        initTheme: function(url) {
            //获取主题
            var theme = myUtils.localGet("theme");
            if (!theme) {
                theme = "coolblacklight";
            }
            //新版本的【动态加载主题】
            if (url == "" || url == undefined) {
                $("#j_theme").attr("href", "../../../css/themes/skin-" + theme + ".css");
            } else {
                $("#j_theme").attr("href", url + theme + ".css");
            }
        },
    View Code

    页面初始化

     

     

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    select语句关键字的定义的顺序、执行顺序on为什么比where先执行?
    Mac 安装和配置Maven
    各平台定时器
    OpenGL画半个球面(62)
    YV12 YUV转RGB
    OpenGL贴图、小图片叠加(10)
    检测当前进程的内存使用情况
    PG之psql特殊使用
    PG中的几种索引方式
    又一例生产案例隐式转换
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/14378697.html
Copyright © 2020-2023  润新知