数据结构中含有图片、名称、children的树形结构,需要展示出每一级的图片名称和图片,找了些树形图的插件,都没有展示大的图片的,一般都是小图标,就自己试着写一个包含图的简单的插件。
<ul>
<li class="tree-item">
<span class="icon glyphicon glyphicon-list-alt"></span>
<a>
<div class="item-name">name1</div>
</a>
<ul>
<li class="tree-item">
<span class="icon glyphicon glyphicon-list-alt"></span>
<a>
<div class="item-name">name2</div>
</a>
</li>
</ul>
</li>
</ul>
主要是用ul和li展示,竖线是用ul的before伪元素写的样式,短横线是li的before伪元素写的样式,要解决的问题是竖线和横线的位置,LI中含有图片和不含有图片LI的class不同,同时li内部的ul的class 也不同,因为含有图片和不含图片设置的样式不一样。整个html结构采用递归的方式。
初始状态是全部展开,点击展开的图标(-)会隐藏同级的UL元素,并改变图标为(+)
$("#tree-box").on("click", ".icon", function() {
$(this).siblings("ul").toggle();
if ($(this).hasClass("glyphicon-minus")) {
$(this).removeClass("glyphicon-minus").addClass("glyphicon-plus")
} else if ($(this).hasClass("glyphicon-plus")) {
$(this).removeClass("glyphicon-plus").addClass("glyphicon-minus")
}
})
如果数据结构是含有PID的,需要先转换成children的数据结构
var json = [
{ id: 1, pid: 0, text: '1(XX公司)' },
{ id: 2, pid: 4, text: '2.1.1(开发部a-1组)' },
{ id: 3, pid: 0, text: '2(开发部)' },
{ id: 4, pid: 3, text: '2.1(开发部a)' },
{ id: 5, pid: 0, text: '3(人事部)' },
{ id: 6, pid: 5, text: '3.1(人事部A)' },
{ id: 7, pid: 0, text: '4(设计部)' },
{ id: 8, pid: 7, text: '4.1(设计部A)' },
{ id: 9, pid: 4, text: '2.1.2(开发部a-2组)' },
{ id: 11, pid: 2, text: '2.1.1.1(开发部a-1组>1小组)' },
{ id: 12, pid: 2, text: '2.1.1.2(开发部a-1组>2小组)' },
{ id: 13, pid: 5, text: '3.2(人事部A)' },
{ id: 19, pid: 5, text: '3.3(人事部B)' }
];
function translateData(data, idStr, pidStr, chindrenStr) {
var result = [],
temp = {},
id = idStr,
pid = pidStr,
children = chindrenStr,
i = 0,
j = 0,
len = data.length;
// 重新把数组中的对象重新放到一个新的对象中,新的对象是以id 的值为键
for (; i < len; i++) {
// 建立temp对象,由于对象是引用类型,修改temp或者data都会引起另一方改变
temp[data[i][id]] = data[i];
// temp[a[i][id]] = JSON.parse(JSON.stringify(data[i])); 这种情况data和temp是独立的
}
// aVal 存储数组中的对象,获取新对象中key为pid 的对象,如果存在
for (; j < len; j++) {
var dataVal = data[j],
tempObj = temp[dataVal[pid]];
if (tempObj) {
// 如果 tempObj[children]不存在,把tempObj[children]设为数组
!tempObj[children] && (tempObj[children] = []);
tempObj[children].push(dataVal);
} else {
// 如果不存在就把dataVal放到结果中
result.push(dataVal);
}
}
console.log(data)
return result;
}
document.getElementById("content").innerHTML = JSON.stringify(translateData(json, 'id', 'pid', 'chindren'), null, 2)
完整的代码
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#box {
margin: 20px;
}
.item-group {
list-style: none;
margin-left: 20px;
position: relative;
}
.item-group:before {
content: "";
display: inline-block;
position: absolute;
top: -10px;
bottom: 15px;
left: 0;
border-left: 1px solid #67b2dd;
z-index: 10;
}
.item-group-innerpic {
list-style: none;
margin-left: 20px;
position: relative;
}
.item-group-innerpic:before {
content: "";
display: inline-block;
position: absolute;
top: -48px;
bottom: 15px;
left: 0;
border-left: 1px solid #67b2dd;
z-index: 10;
}
.tree-item {
position: relative;
line-height: 30px;
}
.tree-item:before {
display: inline-block;
content: "";
position: absolute;
top: 14px;
width: 18px;
height: 0;
border-top: 1px dotted #67b2dd;
}
.tree-item1 {
position: relative;
line-height: 30px;
}
.tree-item1:before {
display: inline-block;
content: "";
position: absolute;
top: 48px;
width: 18px;
height: 0;
border-top: 1px dotted #67b2dd;
}
.item-group li span {
margin-left: 20px;
color: #0994ce;
margin-right: -15px;
}
.item-group li a {
margin-left: 20px;
display:inline-block;
}
.item-group li img {
width:100px;
height: 100px;
margin-right:10px;
}
.item-group li .item-name {
display: inline-block
}
</style>
<div id="tree-box">
</div>
<script src="../js/jquery-2.1.4.min.js"></script>
<script>
var data = [{
title: 'biaoti1',
img: '../imgs/green.png',
children: [{
title: 'biaoti1-1',
img: '../imgs/1.jpg',
children: [{
title: 'biaoti1-1-1'
}, ]
},
{
title: 'biaoti1-2',
children: [{
title: 'biaoti1-2-1',
children: [{
title: 'biaoti1-2-1-1'
},
{
title: 'biaoti1-2-1-2',
children: [{
title: 'biaoti1-2-1-1-1'
},
{
title: 'biaoti1-2-1-1-2'
}
]
}
]
},
{
title: 'biaoti1-2-2'
}
]
},
{
title: 'biaoti1-3'
}
]
},
{
title: 'biaoti2',
children: [{
title: 'biaoti2-1'
},
{
title: 'biaoti2-2'
}
]
},
{
title: 'biaoti3',
children: [{
title: 'biaoti3-1'
},
{
title: 'biaoti3-2'
}
]
},
{
title: 'biaoti4'
}
];
var width = 50;
var ulClass = "item-group"
//封装函数,方便调用
function render(arr, ulClass) {
//设置HTML为ul标签对的前半部分,用以将以下内容包括在ul中
var html = '<ulhljs-string">'">';
//设置循环,遍历数组中的每一项,最长不超过数组的长度,依次遍历
for (var i = 0; i < arr.length; i++) {
//设置第一级ul中的li结构 <li><span>每个标题</span></li>
// console.log(arr[i])
//判断数组arr【i】的下方是否还有结构
if (!arr[i].children) {
if (arr[i].img) {
html += '<li><span></span><a><img src="' + arr[i].img + '" alt=""/><div>' + arr[i].title + '</div></a>';
} else {
html += '<li><span></span><a><div>' + arr[i].title + '</div></a>';
}
} else {
if (arr[i].img) {
html += '<li><span></span><a><img src="' + arr[i].img + '" alt=""/><div>' + arr[i].title + '</div></a>';
html += render(arr[i].children, "item-group-innerpic")
} else {
html += '<li><span></span><a><div>' + arr[i].title + '</div></a>';
html += render(arr[i].children, "item-group")
}
//如果有,就增加结构
}
//设置第一级li的后标签
html += '</li>'
}
//设置第一级ul的后标签
html += '</ul>'
return html;
}
//调用函数,传参数组data,将其赋值给第一级ul的父级结构box,生成动态菜单
var treebox = document.getElementById("tree-box")
treebox.innerHTML = render(data, ulClass);
$("#tree-box").on("click", ".icon", function() {
$(this).siblings("ul").toggle();
if ($(this).hasClass("glyphicon-minus")) {
$(this).removeClass("glyphicon-minus").addClass("glyphicon-plus")
} else if ($(this).hasClass("glyphicon-plus")) {
$(this).removeClass("glyphicon-plus").addClass("glyphicon-minus")
}
//console.log(this)
})
</script>
熟练使用导航栏,对于网站排版非常重要,使用CSS,js,jq等你可以转换成好看的导航栏而不是枯燥的HTML菜单。
1. 首先可以滑出菜单 2. 菜单滑动到一定距离完全滑出,未达到距离回滚 3. 菜单数量、样式随意定制 4. 菜单点击回调 5. 菜单展开时,点击 item 收回菜单,需求明了以后就可以写代码了。
做权限管理,一个核心思想就是后端做权限控制,前端做的所有工作都只是为了提高用户体验,我们不能依靠前端展示或者隐藏一个按钮来实现权限控制,这样肯定是不安全的。就像用户注册时需要输入邮箱地址,前端校验之后,后端还是要校验
在pc 管理系统这种类型的产品,通常会涉及到账号权限的控制,不同的账号权限能浏览的功能模块是不同的,对应侧边栏菜单模块的显示也会不同。单点登录类系统,通常会多个项目公用一套登录系统,项目首页直接就是dashboard 或者 index页面
这是一个相当炫的功能,让网页看起来像桌面程序,如window的开始菜单。实现原理基本和纯CSS相册差不多,但要注意的事项比较多,让我们一步步来吧。
vue-contextmenujs:Vue 原生实现右键菜单组件, 零依赖;npm 安装npm install vue-contextmenujs;测试中使用的是element-ui图标 ;
Vue+Element 实现管理页面菜单栏, 点击菜单时 router 改变 hash 访问不同子组件。但是改变 hash 时菜单栏展开状态和 highlight 并不会同步, 需要手动实现。
本文分别使用 SFC(模板方式)和 tsx 方式对 Element Plus el-menu 组件进行二次封装,实现配置化的菜单,有了配置化的菜单,后续便可以根据路由动态渲染菜单。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!