zoukankan      html  css  js  c++  java
  • 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": []
              }
            ]
          }
        }
      }
    ]
  • 相关阅读:
    php 学习笔记 数组2
    php 学习笔记 数组1
    jQuery prop 全选和全不全
    jquery获取多个checkbox的值异步提交给php
    php 计算多维数组中所有值的总和
    系统状态码原型
    hadoop win10开发环境
    kafka spring整合版本匹配
    mac 安装brew
    hadoop2.8.5 idea2019.1.3插件安装
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/9332280.html
Copyright © 2011-2022 走看看