layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)

声明:这里非常感谢闲心大神,开源了非常好用的前端UI框架,layui,如有侵权请联系我。当然闲心在2.0版本的layuiAdmin已经支持了,不过是收费版的,需要的同学可以自行购买,网址:http://www.layui.com/admin/pro/

本人在做管理后台事用到了左侧的导航列表,但是管理后台进来的菜单是根据不同账户的权限,显示不同的菜单。这时候需要动态的渲染左侧的列表。但是1.0版本只是更新到2级菜单,不满足如下图的3级菜单需求,只能自己动手,改造源码

layui动态渲染生成左侧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
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容