声明:这里非常感谢闲心大神,开源了非常好用的前端UI框架,layui,如有侵权请联系我。当然闲心在2.0版本的layuiAdmin已经支持了,不过是收费版的,需要的同学可以自行购买,网址:http://www.layui.com/admin/pro/
本人在做管理后台事用到了左侧的导航列表,但是管理后台进来的菜单是根据不同账户的权限,显示不同的菜单。这时候需要动态的渲染左侧的列表。但是1.0版本只是更新到2级菜单,不满足如下图的3级菜单需求,只能自己动手,改造源码
话不多说,上代码:
1.html部分,我需要一个容器用于渲染菜单
<div class=\"layui-side layui-bg-black\" id=\"admin-side\"> <div class=\"layui-side-scroll\"> <ul class=\"layui-nav layui-nav-tree\" id=\"nav\" lay-filter=\"demo\"></ul> </div> </div>
接下来是插件以及相关JS,css引入 ,注意:路径问题,换成自己本地的路径
<link rel=\"stylesheet\" href=\"../layui/css/layui.css\" rel=\"external nofollow\" > <script src=\"../lib/jquery-1.12.2.js\" type=\"text/javascript\" charset=\"utf-8\"></script> <script src=\"../layui/layui.js\"></script>
2.js部分
<script> //监听选中页签添加样式 layui.config({ base: \'../layui/\' //navbar组件js所在目录 }).use(\'navbar\', function() { var navbar = layui.navbar(); navbar.set({ elem: \'#nav\', url: \"../layui/nav2.json\" //数据源地址,我用了本地写的json数据 }); navbar.render(); //下面的部分不是必须的 navbar.on(\'click(demo)\', function(data) { console.log(data.elem); console.log(data.field.title);//标题 console.log(data.field.icon);//图标 console.log(data.field.href);//调转地址 layer.msg(data.field.href); }); //给选中的页签添加选中样式(解决刷新失效问题) var url = window.location.href.replace(\"//\", \"\"); var relUrl = url.substring(url.lastIndexOf(\"/\") + 1); //去掉参数部分 if (relUrl.indexOf(\"?\") != -1) { relUrl = relUrl.split(\"?\")[0]; } $(\"#leftNavbar a\").each(function () { var that = this; if ($(that).attr(\"href\") == relUrl) { $(that).parent().addClass(\"layui-this\"); $(that).parents(\"li:eq(0)\").addClass(\"layui-nav-itemed\"); var nodes = $(that).parents(\"li:eq(0)\").find(\"a .layui-nav-more\"); if (nodes.length > 0) { nodes.each(function () { if ($(this).parents(\"dd:eq(0)\").find(\"[href=\'\" + relUrl + \"\']\").length > 0) { $(this).parent().parent().addClass(\"layui-nav-itemed\"); } }); } } }); }); </script>
重点来了:navbar,js
/** * navbar.js * @author 御风 <1945199284@qq.com> */ layui.define([\'element\', \'common\'], function (exports) { \"use strict\"; var $ = layui.jquery, layer = parent.layer === undefined ? layui.layer : parent.layer, element = layui.element, common = layui.common, cacheName = \'tb_navbar\'; var Navbar = function () { /** * 默认配置 */ this.config = { elem: undefined, //容器 data: undefined, //数据源 url: undefined, //数据源地址 type: \'GET\', //读取方式 cached: false, //是否使用缓存 spreadOne: false //设置是否只展开一个二级菜单 }; this.v = \'1.0.0\'; }; //渲染 Navbar.prototype.render = function () { var _that = this; var _config = _that.config; if (typeof (_config.elem) !== \'string\' && typeof (_config.elem) !== \'object\') { common.throwError(\'Navbar error: elem参数未定义或设置出错,具体设置格式请参考文档API.\'); } var $container; if (typeof (_config.elem) === \'string\') { $container = $(\'\' + _config.elem + \'\'); } if (typeof (_config.elem) === \'object\') { $container = _config.elem; } if ($container.length === 0) { common.throwError(\'Navbar error:找不到elem参数配置的容器,请检查.\'); } if (_config.data === undefined && _config.url === undefined) { common.throwError(\'Navbar error:请为Navbar配置数据源.\') } if (_config.data !== undefined && typeof (_config.data) === \'object\') { var html = getHtml(_config.data); $container.html(html); element.init(); _that.config.elem = $container; } else { if (_config.cached) { var cacheNavbar = layui.data(cacheName); if (cacheNavbar.navbar === undefined) { $.ajax({ type: _config.type, url: _config.url, async: false, //_config.async, dataType: \'json\', success: function (result, status, xhr) { //添加缓存 layui.data(cacheName, { key: \'navbar\', value: result }); var html = getHtml(result); $container.html(html); element.init(); }, error: function (xhr, status, error) { common.msgError(\'Navbar error:\' + error); }, complete: function (xhr, status) { _that.config.elem = $container; } }); } else { var html = getHtml(cacheNavbar.navbar); $container.html(html); element.init(); _that.config.elem = $container; } } else { //清空缓存 layui.data(cacheName, null); $.ajax({ type: _config.type, url: _config.url, async: false, //_config.async, dataType: \'json\', success: function (result, status, xhr) { var html = getHtml(result); $container.html(html); element.init(); }, error: function (xhr, status, error) { common.msgError(\'Navbar error:\' + error); }, complete: function (xhr, status) { _that.config.elem = $container; } }); } } //只展开一个二级菜单 if (_config.spreadOne) { var $ul = $container.children(\'ul\'); $ul.find(\'li.layui-nav-item\').each(function () { $(this).on(\'click\', function () { $(this).siblings().removeClass(\'layui-nav-itemed\'); }); }); } return _that; }; /** * 配置Navbar * @param {Object} options */ Navbar.prototype.set = function (options) { var that = this; that.config.data = undefined; $.extend(true, that.config, options); return that; }; /** * 绑定事件 * @param {String} events * @param {Function} callback */ Navbar.prototype.on = function (events, callback) { var that = this; var _con = that.config.elem; if (typeof (events) !== \'string\') { common.throwError(\'Navbar error:事件名配置出错,请参考API文档.\'); } var lIndex = events.indexOf(\'(\'); var eventName = events.substr(0, lIndex); var filter = events.substring(lIndex + 1, events.indexOf(\')\')); if (eventName === \'click\') { if (_con.attr(\'lay-filter\') !== undefined) { _con.children(\'ul\').find(\'li\').each(function () { var $this = $(this); if ($this.find(\'dl\').length > 0) { var $dd = $this.find(\'dd\').each(function () { $(this).on(\'click\', function () { var $a = $(this).children(\'a\'); var href = $a.data(\'url\'); var icon = $a.children(\'i:first\').data(\'icon\'); var title = $a.children(\'cite\').text(); var data = { elem: $a, field: { href: href, icon: icon, title: title } } callback(data); }); }); } else { $this.on(\'click\', function () { var $a = $this.children(\'a\'); var href = $a.data(\'url\'); var icon = $a.children(\'i:first\').data(\'icon\'); var title = $a.children(\'cite\').text(); var data = { elem: $a, field: { href: href, icon: icon, title: title } } callback(data); }); } }); } } }; /** * 清除缓存 */ Navbar.prototype.cleanCached = function () { layui.data(cacheName, null); }; /** * 获取html字符串 * @param {Object} data */ function getHtml(data) { var ulHtml = \'<ul class=\"layui-nav layui-nav-tree beg-navbar\">\'; for (var i = 0; i < data.length; i++) { if (data[i].spread) { ulHtml += \'<li class=\"layui-nav-item layui-nav-itemed\">\'; } else { ulHtml += \'<li class=\"layui-nav-item\">\'; } if (data[i].children !== undefined && data[i].children !== null && data[i].children.length > 0) { ulHtml += \'<a href=\"javascript:;\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" >\' + data[i].title; ulHtml += \'<span class=\"layui-nav-more\"></span>\'; ulHtml += \'</a>\'; ulHtml += \'<dl class=\"layui-nav-child\">\'; //二级菜单 for (var j = 0; j < data[i].children.length; j++) { //是否有孙子节点 if (data[i].children[j].children !== undefined && data[i].children[j].children !== null && data[i].children[j].children.length > 0) { ulHtml += \'<dd>\'; ulHtml += \'<a href=\"javascript:;\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" >\' + data[i].children[j].title; ulHtml += \'<span class=\"layui-nav-more\"></span>\'; ulHtml += \'</a>\'; //三级菜单 ulHtml += \'<dl class=\"layui-nav-child\">\'; var grandsonNodes = data[i].children[j].children; for (var k = 0; k < grandsonNodes.length; k++) { ulHtml += \'<dd>\'; ulHtml += \'<a href=\"\'+ grandsonNodes[k].href +\'\" rel=\"external nofollow\" >\' + grandsonNodes[k].title + \'</a>\'; ulHtml += \'</dd>\'; } ulHtml += \'</dl>\'; ulHtml += \'</dd>\'; }else{ ulHtml += \'<dd>\'; ulHtml += \'<a href=\"\'+data[i].children[j].href+\'\" rel=\"external nofollow\" >\' + data[i].children[j].title; ulHtml += \'</a>\'; ulHtml += \'</dd>\'; } //ulHtml += \'<dd title=\"\' + data[i].children[j].title + \'\">\'; } ulHtml += \'</dl>\'; } else { var dataUrl = (data[i].href !== undefined && data[i].href !== \'\') ? \'data-url=\"\' + data[i].href + \'\"\' : \'\'; //ulHtml += \'<a href=\"javascript:;\" rel=\"external nofollow\" rel=\"external nofollow\" rel=\"external nofollow\" \' + dataUrl + \'>\'; ulHtml += \'<a href=\"\' + data[i].href + \'\" rel=\"external nofollow\" \' + dataUrl + \'>\'; if (data[i].icon !== undefined && data[i].icon !== \'\') { if (data[i].icon.indexOf(\'fa-\') !== -1) { ulHtml += \'<i class=\"fa \' + data[i].icon + \'\" aria-hidden=\"true\" data-icon=\"\' + data[i].icon + \'\"></i>\'; } else { ulHtml += \'<i class=\"layui-icon\" data-icon=\"\' + data[i].icon + \'\">\' + data[i].icon + \'</i>\'; } } ulHtml += \'<cite>\' + data[i].title + \'</cite>\'; ulHtml += \'</a>\'; } ulHtml += \'</li>\'; } ulHtml += \'</ul>\'; return ulHtml; } var navbar = new Navbar(); exports(\'navbar\', function (options) { return navbar.set(options); }); });
公共配置common.js
/** * common.js * @author 御风 <1945199284@qq.com> */ layui.define([\'layer\'], function(exports) { \"use strict\"; var $ = layui.jquery, layer = layui.layer; var common = { /** * 抛出一个异常错误信息 * @param {String} msg */ throwError: function(msg) { throw new Error(msg); return; }, /** * 弹出一个错误提示 * @param {String} msg */ msgError: function(msg) { layer.msg(msg, { icon: 5 }); return; } }; exports(\'common\', common); });
3.返回数据json格式
[ { \"title\": \"首页\", \"icon\": \" \", \"spread\": true, \"href\": \"\" }, { \"title\": \"一级导航\", \"icon\": \"fa-stop-circle\", \"spread\": true, \"href\": \"http://www.baidu.com\", \"children\": [ { \"title\": \"二级导航\", \"icon\": \"\", \"href\": \"lala.html\", \"spread\": true, \"children\": [ { \"title\": \"三级导航\", \"icon\": \" \", \"href\": \"button.html\" }, { \"title\": \"三级导航\", \"icon\": \" \", \"href\": \"buttwswon.html\" } ] } ] }, { \"title\": \"一级导航\", \"icon\": \"fa-stop-circle\", \"spread\": true, \"href\": \"http://www.baidu.com\" }, { \"title\": \"一级导航\", \"icon\": \"fa-stop-circle\", \"spread\": true, \"href\": \"http://www.baidu.com\" }, { \"title\": \"一级导航\", \"icon\": \"fa-stop-circle\", \"spread\": true, \"href\": \"http://www.baidu.com\" } ]
总结:渲染dom,只要的思路就是用了2次for循环,遍历后台返回的数据。
以上这篇layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
© 版权声明
THE END
暂无评论内容