这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战
样式大概是这样的,用的是jquery+layui的方式,之前有人问过,现在分享一下,如果用vue封装成组件应该也不是很难,看懂原理即可。
一、设置界面样式
<!-- 头部 -->
<div class="layui-header" style="background: none;">
<div class="layui-logo" id="logotext" style="font-size: 28px;font-family:'黑体';width: 40%;background: none !important" >
小鲸鱼测试管理系统
</div>
<ul class="layui-nav layui-layout-right" lay-filter="admin-side-nav" lay-accordion="true" style="min-width: 45%;margin-right: 14%;text-align: right;">
<!-- 菜单渲染模板 -->
<script id="sideNav" type="text/html">
{{# layui.each(d, function(index, item){ }}
<li class="layui-nav-item">
<!-- 定义layui自带接口返回跳转页面的地址 -->
<a href="{{item.menuHref?item.menuHref:'javascript:void(0)'}}" lay-href="{{item.menuUrl}}">
<i class="{{item.menuIcon}}"></i> 
<!-- 这里是菜单前面的图片,可以动态判断展示或者接口返回直接用 -->
<img src="./assets/images/setIcon.png" class="jsxsjcIcon">
<cite class="fs16Cite">{{item.name}}</cite><!-- 一级标题名称 -->
</a>
{{# if(item.children&&item.children.length>0){ }}
<dl class="layui-nav-child">
<!-- 第二级菜单 -->
{{# layui.each(item.children, function(index, subItem){ }}
<dd>
<a href="{{ subItem.menuHref }}" title="{{ subItem.name }}" lay-href="{{ subItem.menuUrl }}" data-isRight='{{subItem.children.length}}' class="erRight">
<i class="{{subItem.menuIcon}}"></i> {{ subItem.name }}
{{# if(subItem.children.length > 0){ }}
<i class="layui-icon layui-icon-triangle-r"></i>
{{# } }}
</a>
<!-- 第三级菜单 -->
{{# if(subItem.children.length > 0){ }}
<dl class="rightChildBox" style="display: none">
{{# layui.each(subItem.children, function(index, subTemp){ }}
<dd>
<a href="{{ subTemp.menuHref }}" title="{{ subTemp.name }}" lay-href="{{ subTemp.menuUrl }}" class="sanNav">
<i class="{{subTemp.menuIcon}}"></i> {{ subTemp.name }}
</a>
</dd>
{{# }); }}
</dl>
{{# } }}
</dd>
{{# }); }}
</dl>
{{# } }}
</li>
{{# }); }}
</script>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide-xs" lay-unselect>
<a ew-event="fullScreen" title="全屏"><i class="layui-icon layui-icon-screen-full"></i></a>
</li>
<li class="layui-nav-item" lay-unselect style="margin-right: 10px;">
<a>
<img src="assets/images/head.png" class="layui-nav-img">
<cite id="user-name-index">管理员</cite>
</a>
<dl class="layui-nav-child">
<dd lay-unselect>
<a id="setInfo">个人信息</a>
</dd>
<dd lay-unselect>
<a id="setPsw">修改密码</a>
</dd>
<hr>
<dd lay-unselect>
<a id="btnLogout">退出</a>
</dd>
</dl>
</li>
</ul>
</div>
这里页面定义的地方,主要用到layui提供的模板引擎,如果是vue开发就可以直接用template的模板语法写,通过循环的方法吧三级菜单展示出来,如果还有更多级别也可以增加渲染,或者想着用递归的方式写?现在这样循环看起来有点多,不太好复用的样子。
二、定义菜单数据
let menus = [
{
"id":"1001",
"parentId":"-1",
"children":[],
"name":"用户管理",
"menuHref":"#!xjy-userInfo",
"menuUrl":"/view/userInfo.html",
},{
"id":"1002",
"parentId":"-1",
"children":[
{
"id":"100201",
"children":[],
"name":"系统管理",
"menuHref":"#!xjy-system",
"menuUrl":"/view/system.html",
},{
"id":"100202",
"children":[
{
"id":"10020201",
"children":[],
"name":"角色管理",
"menuHref":"#!xjy-role",
"menuUrl":"/view/role.html",
},{
"id":"10020202",
"children":[
{
"id":"1002020101",
"children":[],
"name":"个人账号",
"menuHref":"#!xjy-userAccount",
"menuUrl":"/view/userAccount.html",
},{
"id":"1002020102",
"children":[],
"name":"公用账号",
"menuHref":"#!xjy-companyAccount",
"menuUrl":"/view/companyAccount.html",
}
],
"name":"账号管理",
"menuHref":"#!xjy-account",
"menuUrl":"/view/account.html",
}
]
}
]
}
}]
这里可以是接口返回的数据,我这里写死了,就是一个json数组,里面用children来判断是否有下级,其实还有parentId来判断是否有第一级,我看数据太多了就删掉了。
三、渲染到页面上
laytpl(sideNav.innerHTML).render(menus, function (html) {
$('*[lay-filter=admin-side-nav]').html(html);
element.render('nav');
});
laytpl是layui自带的模板引擎,引用定义一下,sideNav是模板引擎。
四、悬停展示二级菜单,悬停二级菜单展示三级菜单,点击并跳转
//三级菜单悬停展示
let isHoverSanNav = false;
let erEl = null;
setTimeout(() => {
$(".erRight").hover(function() {
$(this).siblings().show();
},function() {
erEl = $(this);
setTimeout(function() {
if(!isHoverSanNav) {
erEl.siblings().hide();
}
},100)
})
$(".sanNav").hover(function() {
$(this).parent().parent().show();
isHoverSanNav = true;
},function() {
isHoverSanNav = false;
$(this).parent().parent().hide();
})
},1000)
这里是最麻烦的,因为要悬停展示下拉菜单,用到的第一级菜单是layUi自带的,第二级菜单悬停就需要自己写了,定义一个外部变量isHoverSanNav来判断是否展示第三级菜单,并定义一个erEl代表悬停的第二级菜单的dom元素,后面在悬停隐藏的时候再把第三级菜单隐藏掉。
设置setTimeout延时是给点击事件提供事件,因为点击事件是画html的时候用a标签超链接自带的。然后hover第一个方法是悬停展示的内容,第二个方法是设置隐藏div菜单栏的方法,悬停第二级展示第三级菜单。