react style: 二级菜单
1、样式
@import "../../styles/varibles"; .app-sidebar {
overflow: hidden;
width: 180px; > ul > li {
position: relative;
font-size: $font-lg;
border-bottom: $border;
border-right: $border;
border-left: $border; &:first-child {
border-top: $border;
border-top-right-radius: $border-radius;
border-top-left-radius: $border-radius;
} &:last-child {
border-bottom-right-radius: $border-radius;
border-bottom-left-radius: $border-radius;
}
} .active {
border-left: 3px solid $primary-color;
background-color: $item-active-bg-color;
a {
font-weight: bold;
}
} .nav-item {
.item-name {
margin-right: 30px;
height: 50px;
line-height: 50px;
}
.anticon {
position: absolute;
height: 50px;
line-height: 50px;
left: 7px;
font-size: $font-sm;
color: $title-color;
}
} &.is-open {
.anticon {
color: $primary-color;
}
.nav-item-content {
color: $title-color;
font-weight: bold;
}
}
&:hover {
.anticon,
.nav-item-content {
color: $primary-color;
}
}
&:active {
.nav-item-content {
color: $primary-color;
font-weight: bold;
}
}
.sub-menu {
border-top: none;
font-size: $font-sm; .item-name {
height: 40px;
line-height: 40px;
} .child-nav-item.active {
.item-name {
color: $primary-color;
font-weight: bold;
}
}
}
}
2、js文件
import React from "react";
import {withRouter} from "react-router-dom";
import {Icon} from "antd";
import _ from "lodash";
const menus = [];
const currentState = ''; class Sidebar extends React.Component { componentDidMount() {
const defaultNavItem = this.getDefaultNavItem();
if (defaultNavItem === undefined) {
this.props.history.replace('/forbidden');
return;
}
this.setActiveNavItem(defaultNavItem);
this.openNavItem(defaultNavItem);
if (this.hasChildItems(defaultNavItem)) {
this.setActiveChildNavItem(defaultNavItem.childItems);
}
} getDefaultNavItem() {
const currentState = currentState;
return _.find(menus, function (navItem) {
if (navItem.state === currentState || _.some(navItem.childItems, {state: currentState})) {
return navItem;
}
})
} setActiveNavItem(navItem) {
if (this.hasChildItems(navItem)) {
this.clearParentActiveStatus();
}else {
this.clearActiveStatusWithChildItems();
navItem.isActive = true;
if (!!navItem.state) {
this.props.history.replace(navItem.state);
}
}
} setActiveChildNavItem(childNavItems) {
const currentState = currentState;
this.clearActiveStatusWithChildItems();
if (_.isArray(childNavItems)) {
childNavItems.forEach(function (navItem) {
navItem.isActive = navItem.state === currentState;
});
}else {
childNavItems.isActive = true;
}
} openNavItem(navItem) {
navItem.isOpen = this.hasChildItems(navItem);
this.forceUpdate();
} onOpenNavItem(navItem) {
if (this.hasChildItems(navItem)) {
navItem.isOpen = !navItem.isOpen;
}else {
navItem.isOpen = false;
}
this.forceUpdate();
} clearParentActiveStatus() {
menus.forEach(function (navItem) {
navItem.isActive = false;
})
} clearActiveStatusWithChildItems() {
menus.forEach(function (navItem) {
navItem.isActive = false;
navItem.childItems.forEach(function (childItem) {
childItem.isActive = false;
})
})
} hasChildItems(navItem) {
return !!navItem.childItems && navItem.childItems.length > 0;
} menuIcon(navItem) {
return <Icon type={navItem.isOpen ? 'caret-down' : 'caret-right'}/>
} openOrActiveClass(navItem) {
const basic = "nav-item";
const openClass = navItem.isOpen ? "is-open" : "";
const activeClass = navItem.isActive ? "active" : "";
return basic + " " + openClass + " " + activeClass;
} activeClass(navItem) {
const basic = "child-nav-item";
const activeClass = navItem.isActive ? "active" : "";
return basic + " " + activeClass;
} render() {
return (
<aside className="app-sidebar">
<ul className="list-unstyled menu">
{
menus.map((navItem, index) => {
return (
<li key={'li_'+index} className={this.openOrActiveClass(navItem)}>
<span key={'span' + index}
className="item-name nav-item-content"
onClick={() => {
this.setActiveNavItem(navItem);
this.onOpenNavItem(navItem)
}}>
{this.hasChildItems(navItem) ? this.menuIcon(navItem) : null}
{navItem.name}
</span>
{
navItem.isOpen ?
<ul key={'subMenu_ul'} className="list-unstyled sub-menus">
{
navItem.childItems.map((childItem, itemIndex) => {
return (
<li key={'submenu_li_' + itemIndex}
className={this.activeClass(childItem)}
onClick={() => {
this.setActiveChildNavItem(childItem);
this.setActiveNavItem(childItem)
}}>
<a className="item-name">{childItem.name}</a>
</li>
)
})
}
</ul> : null
}
</li>
)
})
}
</ul>
</aside>
)
}
} export default withRouter(Sidebar);
3、数据
[
{
"description": "userCanGetMenus",
"request": {
"method": "GET",
"uri": "/api/menus"
},
"response": {
"status": 200,
"json": {
"id": "DEMO0000",
"fatherId": "00000000",
"state": "process",
"name": "运营流程",
"childItems": [
{
"id": "DEMO1000",
"fatherId": "DEMO0000",
"state": "/process.personal-task-pool",
"name": "个人任务池",
"childItems": []
},
{
"id": "DEMO2000",
"fatherId": "DEMO0000",
"state": "/process.common-task-pool",
"name": "公共任务池",
"childItems": []
},
{
"id": "DEMO1000",
"fatherId": "DEMO0000",
"state": "/process.launch",
"name": "流程发起",
"childItems": []
},
{
"id": "DEMO1000",
"fatherId": "DEMO0000",
"state": "/process.search",
"name": "流程查询",
"childItems": []
}
]
}
}
}
]
react style: 二级菜单的更多相关文章
- react 侧栏二级菜单组件
侧边栏菜单组件 component 下新建menu文件,menu下建index.jsx和subitem.jsx index.jsx import React, { Component } from ' ...
- Jquery垂直下拉二级菜单
自己做了一个基于Jquery 的垂直下拉二级菜单功能,直接看图: Html的代码如下: <!DOCTYPE html> <html> <head> <meta ...
- JS实现的简单横向伸展二级菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JS-鼠标经过显示二级菜单
在css处添加了border样式为了看得更清楚——源代码有一个程序漏洞,存在一个很烦人的大bug. <ul class="nav"> <li class=&quo ...
- 转:jQuery弹出二级菜单
<html> <head> <meta http-equiv="content-type" content="text/html; char ...
- html+css二级菜单制作!
二级菜单!!<!DOCTYPE html<html lang="e<head> <meta charset="UTF-8"> < ...
- js运动:多div变宽、二级菜单
定时器及运动函数. 多div变宽: <!-- Author: XiaoWen Create a file: 2016-12-13 09:36:30 Last modified: 2016-12- ...
- javascript 特效实现(3)—— 鼠标滑过显示二级菜单效果
1. 关键代码:使用 switch 或 if 判断语句,改变对应的二级菜单显示方式为 block 或 none function selectTabMenu(i){ switch(i){ case 7 ...
- jquery垂直展开折叠手风琴二级菜单
摘要:jquery实现垂直展开二级菜单 最近新开发一个简单项目,用到左侧两级的菜单.找找了手头的文件,竟然没有现成的代码,算了,去网上找找整理下吧. 注:jquery-1.8.3.min.js需要下载 ...
随机推荐
- Web框架(Day64)
阅读目录 http协议 web应用与web框架 一.http协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World W ...
- beego——事务处理和命令模式
1.事务处理 ORM 可以简单的进行事务操作. o := NewOrm() err := o.Begin() // 事务处理过程 ... ... // 此过程中的所有使用 o Ormer 对象的查询都 ...
- java.text.SimpleDateFormat使用介绍
java.text.SimpleDateFormat的使用 java.lang.Object | +----java.text.Format | +-- ...
- SpringBoot学习笔记(14):使用SpringBootAdmin管理监控你的应用
SpringBoot学习笔记(14):使用SpringBootAdmin管理监控你的应用 Spring Boot Admin是一个管理和监控Spring Boot应用程序的应用程序.本文参考文档: 官 ...
- 查询前几条记录 top limit
SQL Server 数据库中的Top关键字可实现查询数据库表中的前几条数据,但是需要注意的是,Top关键字只能在SQL Server数据库中可以使用,而在MySQL数据库中就要使用具有同样功能的LI ...
- 20145217《网络对抗》web基础
20145217<网络对抗>web基础 一.问题 1.什么是表单? 表单:可以收集用户的信息和反馈意见,是网站管理者与浏览者之间沟通的桥梁. 表单包括两个部分:一部分是HTML源代码用于描 ...
- yum安装mysql后root用户的临时密码
1.查看root用户临时随机密码 yum 安装mysql后,无法通过空密码登录数据库,如下: [root@ mysql]# mysql -u root -p Enter password: ERROR ...
- RBAC权限控制
1.什么是RBAC权限模型rity2.RBAC权限模型表设计3.整合Mybatis数据库4.UserDetailsService5.动态查询数据库登陆6.动态权限角色拦截 什么是RBAC权限模型r 基 ...
- LOJ 一本通一句话题解系列:
第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...
- bootstrap正则表达式验证手机 座机 邮箱
$('#CusForm').bootstrapValidator({ fields : { //验证手机 'customer.mobile' : { //input中的name 值 validator ...