一. 前端规范设计
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表单内容序列化等等。
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//帮助类 //暂定需要封装:缓存、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(""); } };
特别注意这里的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。
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <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>(); //返回空集合 } }
(2). 前端js
代码分享:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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', '系统设置'); //默认展开的选项卡名称 }); }, }
三. 其它
1. 设置主题
大致思路:EasyUI有个样式库,命名规则为:skin-xxx.css,如下图:
(1). 每个页面引入一个默认样式,如:
<link href="css/themes/skin-coolblacklight.css" rel="stylesheet" id="j_theme" />
(2). 设置主题页面,选择对应的主题,存入缓存中(实质上就是存入了 skin- 后面的内容),并刷新页面。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<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>
每次打开该页面的时候,从缓存中读取,如果没有则为默认样式,然后给下面弹框设置选中。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
$("#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'); });
效果图:
(3). 然后每个页面都要初始化一下,从缓存中读取,然后替换 步骤1 中link引入的样式文件。
方法封装
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//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"); } },
页面初始化
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。