1、样式

  1. @import "../../styles/varibles";
  2.  
  3. .app-sidebar {
  4. overflow: hidden;
  5. width: 180px;
  6.  
  7. > ul > li {
  8. position: relative;
  9. font-size: $font-lg;
  10. border-bottom: $border;
  11. border-right: $border;
  12. border-left: $border;
  13.  
  14. &:first-child {
  15. border-top: $border;
  16. border-top-right-radius: $border-radius;
  17. border-top-left-radius: $border-radius;
  18. }
  19.  
  20. &:last-child {
  21. border-bottom-right-radius: $border-radius;
  22. border-bottom-left-radius: $border-radius;
  23. }
  24. }
  25.  
  26. .active {
  27. border-left: 3px solid $primary-color;
  28. background-color: $item-active-bg-color;
  29. a {
  30. font-weight: bold;
  31. }
  32. }
  33.  
  34. .nav-item {
  35. .item-name {
  36. margin-right: 30px;
  37. height: 50px;
  38. line-height: 50px;
  39. }
  40. .anticon {
  41. position: absolute;
  42. height: 50px;
  43. line-height: 50px;
  44. left: 7px;
  45. font-size: $font-sm;
  46. color: $title-color;
  47. }
  48. }
  49.  
  50. &.is-open {
  51. .anticon {
  52. color: $primary-color;
  53. }
  54. .nav-item-content {
  55. color: $title-color;
  56. font-weight: bold;
  57. }
  58. }
  59. &:hover {
  60. .anticon,
  61. .nav-item-content {
  62. color: $primary-color;
  63. }
  64. }
  65. &:active {
  66. .nav-item-content {
  67. color: $primary-color;
  68. font-weight: bold;
  69. }
  70. }
  71. .sub-menu {
  72. border-top: none;
  73. font-size: $font-sm;
  74.  
  75. .item-name {
  76. height: 40px;
  77. line-height: 40px;
  78. }
  79.  
  80. .child-nav-item.active {
  81. .item-name {
  82. color: $primary-color;
  83. font-weight: bold;
  84. }
  85. }
  86. }
  87. }

2、js文件

  1. import React from "react";
  2. import {withRouter} from "react-router-dom";
  3. import {Icon} from "antd";
  4. import _ from "lodash";
  5. const menus = [];
  6. const currentState = '';
  7.  
  8. class Sidebar extends React.Component {
  9.  
  10. componentDidMount() {
  11. const defaultNavItem = this.getDefaultNavItem();
  12. if (defaultNavItem === undefined) {
  13. this.props.history.replace('/forbidden');
  14. return;
  15. }
  16. this.setActiveNavItem(defaultNavItem);
  17. this.openNavItem(defaultNavItem);
  18. if (this.hasChildItems(defaultNavItem)) {
  19. this.setActiveChildNavItem(defaultNavItem.childItems);
  20. }
  21. }
  22.  
  23. getDefaultNavItem() {
  24. const currentState = currentState;
  25. return _.find(menus, function (navItem) {
  26. if (navItem.state === currentState || _.some(navItem.childItems, {state: currentState})) {
  27. return navItem;
  28. }
  29. })
  30. }
  31.  
  32. setActiveNavItem(navItem) {
  33. if (this.hasChildItems(navItem)) {
  34. this.clearParentActiveStatus();
  35. }else {
  36. this.clearActiveStatusWithChildItems();
  37. navItem.isActive = true;
  38. if (!!navItem.state) {
  39. this.props.history.replace(navItem.state);
  40. }
  41. }
  42. }
  43.  
  44. setActiveChildNavItem(childNavItems) {
  45. const currentState = currentState;
  46. this.clearActiveStatusWithChildItems();
  47. if (_.isArray(childNavItems)) {
  48. childNavItems.forEach(function (navItem) {
  49. navItem.isActive = navItem.state === currentState;
  50. });
  51. }else {
  52. childNavItems.isActive = true;
  53. }
  54. }
  55.  
  56. openNavItem(navItem) {
  57. navItem.isOpen = this.hasChildItems(navItem);
  58. this.forceUpdate();
  59. }
  60.  
  61. onOpenNavItem(navItem) {
  62. if (this.hasChildItems(navItem)) {
  63. navItem.isOpen = !navItem.isOpen;
  64. }else {
  65. navItem.isOpen = false;
  66. }
  67. this.forceUpdate();
  68. }
  69.  
  70. clearParentActiveStatus() {
  71. menus.forEach(function (navItem) {
  72. navItem.isActive = false;
  73. })
  74. }
  75.  
  76. clearActiveStatusWithChildItems() {
  77. menus.forEach(function (navItem) {
  78. navItem.isActive = false;
  79. navItem.childItems.forEach(function (childItem) {
  80. childItem.isActive = false;
  81. })
  82. })
  83. }
  84.  
  85. hasChildItems(navItem) {
  86. return !!navItem.childItems && navItem.childItems.length > 0;
  87. }
  88.  
  89. menuIcon(navItem) {
  90. return <Icon type={navItem.isOpen ? 'caret-down' : 'caret-right'}/>
  91. }
  92.  
  93. openOrActiveClass(navItem) {
  94. const basic = "nav-item";
  95. const openClass = navItem.isOpen ? "is-open" : "";
  96. const activeClass = navItem.isActive ? "active" : "";
  97. return basic + " " + openClass + " " + activeClass;
  98. }
  99.  
  100. activeClass(navItem) {
  101. const basic = "child-nav-item";
  102. const activeClass = navItem.isActive ? "active" : "";
  103. return basic + " " + activeClass;
  104. }
  105.  
  106. render() {
  107. return (
  108. <aside className="app-sidebar">
  109. <ul className="list-unstyled menu">
  110. {
  111. menus.map((navItem, index) => {
  112. return (
  113. <li key={'li_'+index} className={this.openOrActiveClass(navItem)}>
  114. <span key={'span' + index}
  115. className="item-name nav-item-content"
  116. onClick={() => {
  117. this.setActiveNavItem(navItem);
  118. this.onOpenNavItem(navItem)
  119. }}>
  120. {this.hasChildItems(navItem) ? this.menuIcon(navItem) : null}
  121. {navItem.name}
  122. </span>
  123. {
  124. navItem.isOpen ?
  125. <ul key={'subMenu_ul'} className="list-unstyled sub-menus">
  126. {
  127. navItem.childItems.map((childItem, itemIndex) => {
  128. return (
  129. <li key={'submenu_li_' + itemIndex}
  130. className={this.activeClass(childItem)}
  131. onClick={() => {
  132. this.setActiveChildNavItem(childItem);
  133. this.setActiveNavItem(childItem)
  134. }}>
  135. <a className="item-name">{childItem.name}</a>
  136. </li>
  137. )
  138. })
  139. }
  140. </ul> : null
  141. }
  142. </li>
  143. )
  144. })
  145. }
  146. </ul>
  147. </aside>
  148. )
  149. }
  150. }
  151.  
  152. export default withRouter(Sidebar);

3、数据

  1. [
  2. {
  3. "description": "userCanGetMenus",
  4. "request": {
  5. "method": "GET",
  6. "uri": "/api/menus"
  7. },
  8. "response": {
  9. "status": 200,
  10. "json": {
  11. "id": "DEMO0000",
  12. "fatherId": "00000000",
  13. "state": "process",
  14. "name": "运营流程",
  15. "childItems": [
  16. {
  17. "id": "DEMO1000",
  18. "fatherId": "DEMO0000",
  19. "state": "/process.personal-task-pool",
  20. "name": "个人任务池",
  21. "childItems": []
  22. },
  23. {
  24. "id": "DEMO2000",
  25. "fatherId": "DEMO0000",
  26. "state": "/process.common-task-pool",
  27. "name": "公共任务池",
  28. "childItems": []
  29. },
  30. {
  31. "id": "DEMO1000",
  32. "fatherId": "DEMO0000",
  33. "state": "/process.launch",
  34. "name": "流程发起",
  35. "childItems": []
  36. },
  37. {
  38. "id": "DEMO1000",
  39. "fatherId": "DEMO0000",
  40. "state": "/process.search",
  41. "name": "流程查询",
  42. "childItems": []
  43. }
  44. ]
  45. }
  46. }
  47. }
  48. ]

react style: 二级菜单的更多相关文章

  1. react 侧栏二级菜单组件

    侧边栏菜单组件 component 下新建menu文件,menu下建index.jsx和subitem.jsx index.jsx import React, { Component } from ' ...

  2. Jquery垂直下拉二级菜单

    自己做了一个基于Jquery 的垂直下拉二级菜单功能,直接看图: Html的代码如下: <!DOCTYPE html> <html> <head> <meta ...

  3. JS实现的简单横向伸展二级菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. JS-鼠标经过显示二级菜单

    在css处添加了border样式为了看得更清楚——源代码有一个程序漏洞,存在一个很烦人的大bug. <ul class="nav"> <li class=&quo ...

  5. 转:jQuery弹出二级菜单

    <html> <head> <meta http-equiv="content-type" content="text/html; char ...

  6. html+css二级菜单制作!

    二级菜单!!<!DOCTYPE html<html lang="e<head> <meta charset="UTF-8"> < ...

  7. js运动:多div变宽、二级菜单

    定时器及运动函数. 多div变宽: <!-- Author: XiaoWen Create a file: 2016-12-13 09:36:30 Last modified: 2016-12- ...

  8. javascript 特效实现(3)—— 鼠标滑过显示二级菜单效果

    1. 关键代码:使用 switch 或 if 判断语句,改变对应的二级菜单显示方式为 block 或 none function selectTabMenu(i){ switch(i){ case 7 ...

  9. jquery垂直展开折叠手风琴二级菜单

    摘要:jquery实现垂直展开二级菜单 最近新开发一个简单项目,用到左侧两级的菜单.找找了手头的文件,竟然没有现成的代码,算了,去网上找找整理下吧. 注:jquery-1.8.3.min.js需要下载 ...

随机推荐

  1. 004-React入门概述

    一.概述 参考地址:https://reactjs.org/docs/try-react.html 1.1.本地快速体验 <!DOCTYPE html> <html> < ...

  2. composer 常用包管理工具

    名称 用途说明 说明地址 mashape/unirest-php 简单易用的HTTP请求库 官网地址 guzzlehttp/guzzle 功能强大的HTTP请求库 文档 hassankhan/conf ...

  3. NUnit TestFixtureSetup 和 TestFixtureTearDown

    TestFixtureSetup 和 TestFixtureTearDown 在所有测试开始前(TestFixtureSetup)或结束后(TestFixtureTearDown)运行一 次.记住他只 ...

  4. url监控

    #!/usr/bin/env python #coding:utf-8 import MySQLdb,requests import time from datetime import datetim ...

  5. 大数据生态,哪些框架需要全部启动,哪些只启动master,仅为汇总

    主从,只需要在master节点启动 hadoop hbase 单机启动 hive 其他,需要启动每个节点 zookeeper kafka flume presto

  6. C# Json格式

    using LitJson; //自定义Json类 JsonDataResult jsondata = new JsonDataResult() { Success = false }; HttpCo ...

  7. LVS持久化

    在实际应用场景中,轮询调度并不都是适用的.有些情况下,需要我们把同一个会话的请求都调度给一个RS节点.这时候就需要LVS提供持久化的能力,能够实现会话保持. 一.LVS的持久化主要包括以下两个方面. ...

  8. GIT使用—创建一个版本库

    一.GIT命令行 [root@localhost ~]# git usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] ...

  9. jQuery单选多选按钮选中美化特效

    在线演示 本地下载

  10. Java结对编程四则运算一周小结

    Java结对编程四则运算一周小结 需求分析 对于四则运算来说最主要的就是要计算出产生的式子(字符串的形式). 设计思路 总体可将这个项目分解为几个部分:产生式子,计算式子,判断对错并记录: 具体的思路 ...