layui動態(tài)渲染生成左側(cè)3級菜單的方法(根據(jù)后臺返回數(shù)據(jù))
聲明:這里非常感謝閑心大神,開源了非常好用的前端UI框架,layui,如有侵權(quán)請聯(lián)系我。當(dāng)然閑心在2.0版本的layuiAdmin已經(jīng)支持了,不過是收費(fèi)版的,需要的同學(xué)可以自行購買,網(wǎng)址:http://www.layui.com/admin/pro/
本人在做管理后臺事用到了左側(cè)的導(dǎo)航列表,但是管理后臺進(jìn)來的菜單是根據(jù)不同賬戶的權(quán)限,顯示不同的菜單。這時候需要動態(tài)的渲染左側(cè)的列表。但是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>
接下來是插件以及相關(guān)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>
//監(jiān)聽選中頁簽添加樣式
layui.config({
base: '../layui/' //navbar組件js所在目錄
}).use('navbar', function() {
var navbar = layui.navbar();
navbar.set({
elem: '#nav',
url: "../layui/nav2.json" //數(shù)據(jù)源地址,我用了本地寫的json數(shù)據(jù)
});
navbar.render();
//下面的部分不是必須的
navbar.on('click(demo)', function(data) {
console.log(data.elem);
console.log(data.field.title);//標(biāo)題
console.log(data.field.icon);//圖標(biāo)
console.log(data.field.href);//調(diào)轉(zhuǎn)地址
layer.msg(data.field.href);
});
//給選中的頁簽添加選中樣式(解決刷新失效問題)
var url = window.location.href.replace("http://", "");
var relUrl = url.substring(url.lastIndexOf("/") + 1);
//去掉參數(shù)部分
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>
重點(diǎn)來了:navbar,js
/**
* navbar.js
* @author 御風(fēng) <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 () {
/**
* 默認(rèn)配置
*/
this.config = {
elem: undefined, //容器
data: undefined, //數(shù)據(jù)源
url: undefined, //數(shù)據(jù)源地址
type: 'GET', //讀取方式
cached: false, //是否使用緩存
spreadOne: false //設(shè)置是否只展開一個二級菜單
};
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參數(shù)未定義或設(shè)置出錯,具體設(shè)置格式請參考文檔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參數(shù)配置的容器,請檢查.');
}
if (_config.data === undefined && _config.url === undefined) {
common.throwError('Navbar error:請為Navbar配置數(shù)據(jù)源.')
}
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++) {
//是否有孫子節(jié)點(diǎn)
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 御風(fēng) <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.返回數(shù)據(jù)json格式
[
{
"title": "首頁",
"icon": " ",
"spread": true,
"href": ""
},
{
"title": "一級導(dǎo)航",
"icon": "fa-stop-circle",
"spread": true,
"href": "http://www.baidu.com",
"children": [
{
"title": "二級導(dǎo)航",
"icon": "",
"href": "lala.html",
"spread": true,
"children": [
{
"title": "三級導(dǎo)航",
"icon": " ",
"href": "button.html"
},
{
"title": "三級導(dǎo)航",
"icon": " ",
"href": "buttwswon.html"
}
]
}
]
},
{
"title": "一級導(dǎo)航",
"icon": "fa-stop-circle",
"spread": true,
"href": "http://www.baidu.com"
},
{
"title": "一級導(dǎo)航",
"icon": "fa-stop-circle",
"spread": true,
"href": "http://www.baidu.com"
},
{
"title": "一級導(dǎo)航",
"icon": "fa-stop-circle",
"spread": true,
"href": "http://www.baidu.com"
}
]
總結(jié):渲染dom,只要的思路就是用了2次for循環(huán),遍歷后臺返回的數(shù)據(jù)。
以上這篇layui動態(tài)渲染生成左側(cè)3級菜單的方法(根據(jù)后臺返回數(shù)據(jù))就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- layui動態(tài)渲染生成select的option值方法
- layui的布局和表格的渲染以及動態(tài)生成表格的方法
- 解決使用layui的時候form表單中的select等不能渲染的問題
- 淺談layui使用模板引擎動態(tài)渲染元素要注意的問題
- layui使用表格渲染獲取行數(shù)據(jù)的例子
- layui問題之渲染數(shù)據(jù)表格時,僅出現(xiàn)10條數(shù)據(jù)的解決方法
- 解決layui 表單元素radio不顯示渲染的問題
- 使用layui 渲染table數(shù)據(jù)表格的實(shí)例代碼
- layui框架table 數(shù)據(jù)表格的方法級渲染詳解
- layUI ajax加載html頁面后重新渲染的方法
- 解決Layui當(dāng)中的導(dǎo)航條動態(tài)添加后渲染失敗的問題
相關(guān)文章
javascript數(shù)組中的concat方法和splice方法
這篇文章主要介紹了javascript數(shù)組中的concat方法和splice方法,concat方法作用合并數(shù)組,可以合并一個或多個數(shù)組,會返回合并數(shù)組之后的數(shù)據(jù),不會改變原來的數(shù)組,更多相關(guān)內(nèi)容需要的小伙伴可以參考下面文章內(nèi)容2022-03-03
微信小程序?qū)W習(xí)(4)-系統(tǒng)配置app.json詳解
我們使用app.json文件來對微信小程序進(jìn)行全局配置,決定頁面文件的路徑、窗口表現(xiàn)、設(shè)置網(wǎng)絡(luò)超時時間、設(shè)置多 tab 等。2017-01-01
JavaScript仿小米實(shí)現(xiàn)球體分解動畫
用過小米手機(jī)的應(yīng)該見過它的垃圾清理ui界面吧,本文將利用JavaScript模擬這一界面實(shí)現(xiàn)球體分解動畫,感興趣的小伙伴可以學(xué)習(xí)一下2022-06-06
javascript當(dāng)中的代碼嗅探擴(kuò)展原生對象和原型(prototype)
如果不是有特殊需要而去擴(kuò)展原生對象和原型(prototype)的做法是不好的,除非這樣做是值得的,例如,向一些舊的瀏覽器中添加一些ECMAScript5中的方法2013-01-01
JavaScript 高仿真可控彈簧振子實(shí)現(xiàn)代碼
我剛學(xué)JavaScript ,看見一些牛人寫了許多特效,我也花了一天寫了一個彈簧振子,完全獨(dú)創(chuàng),沒有借鑒任何人的代碼.2009-10-10

