• react: menuService


    1、获取菜单对象

    static findCurrentItem(items, currentState, currentItem) {
            _.forEach(items, function (item) {
                if (item.state === currentState) {
                    currentItem.push(item);
                } else if (MenuService.hasChildItems(item)) {
                    MenuService.findCurrentItem(item.childItems, currentState, currentItem);
                }
            })
        }
    
        static findParentItem(items, currentItem, parentItem) {
            const fatherItem = _.find(items, {id: currentItem.fatherId});
            if (_.isEmpty(fatherItem)) {
                _.forEach(items, function (item) {
                    if (MenuService.hasChildItems(item)) {
                        MenuService.findParentItem(item.childItems, currentItem, parentItem);
                    }
                })
            } else {
                parentItem.push(fatherItem);
            }
        }
    
        static hasChildItems(item) {
            return !!item.childItems && item.childItems.length > 0;
        }
    
    getCurrentItem(menus, currentState) {
            const currentItem = [];
            MenuService.findCurrentItem(menus, currentState, currentItem);
            return currentItem[0];
        }
    
        getParentItem(menus, currentItem) {
            const parentItem = [];
            MenuService.findParentItem(menus, currentItem, parentItem);
            return parentItem[0];
        }

    2、获取实际页面module

    getModules(menuTree) {
            const modules = [];
            _.forIn(menuTree, function (value, key) {
                if (!_.isEmpty(value)) {
                    const moduleItem = {};
                    const moduleItems = [];
                    _.set(moduleItem, 'type', key);
                    MenuService.findModuleItem(moduleItems, value);
                    _.set(moduleItem, 'state', moduleItems[0]);
                    modules.push(moduleItem);
                }
            });
            return modules;
        }
    
        static findModuleItem(moduleItems, menuTreeValue) {
            _.forEach(menuTreeValue, function (item) {
                if (item.state.indexOf('.') !== -1) {
                    moduleItems.push(_.get(item, 'state'));
                } else if (MenuService.hasChildItems(item)) {
                    MenuService.findModuleItem(moduleItems, item.childItems);
                }
            })
        }

    3、获取默认路由

    getDefaultState(menuTree) {
            const modules = this.getModules(menuTree);
            if (!_.isEmpty(modules)) {
                return _.get(modules[0], 'state');
            }
        }

    4、获取menus

    getMenu() {
            return new Promise((resolve, reject) => {
                axiosService.request({
                    url: '/api/menus',
                    method: 'GET'
                }).then(res => {
                    const menuTree = {};
                    const navigators = {};
                    _.forEach(res.data, function (item) {
                        _.set(menuTree, item.state, item.childItems);
                        _.set(navigators, item.state, item.name);
                    });
                    const menu = {
                        menuTree,
                        navigators,
                        defaultState: this.getDefaultState(menuTree),
                        modules: this.getModules(menuTree)
                    };
                    typeof resolve === 'function' && resolve(menu);
                }).catch(error => {
                    typeof reject === 'function' && reject(error);
                })
            })
        }
    
        getSidebarMenu(menuTree, nav) {
            return _.result(menuTree, nav);
        }

    menuTree: 集合,里面包含一个nav,一个对应该nav的菜单item

    [{"nav01": [nav01.menus01]},{"nav02": [nav01.menus02]}];

    navigators: 一个nav,一个对应nav的名字

    [{"nav01": "nav01.name"},{"nav02": "nav01.name"}];

    modules: 一个nav,一个对应nav的第一个路由

    [{"nav01": "nav01.defaultState01"},{"nav02": "nav01.defaultState02"}];

    redux menu data:

    import React from "react";
    import {connect} from "react-redux";
    import {withRouter} from "react-router-dom";
    import {Icon} from "antd";
    import _ from "lodash";
    import "./index.scss"
    
    const mapStateToProps = state => {
        return {
            menuData: state.MenuReducer.data
        }
    };
    
    class Sidebar extends React.Component {
    
        constructor(props) {
            super(props);
            this.currentState = props.location.pathname;
            this.menus = _.result(props.menuData.menuTree, props.nav);
        }
    
        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 = this.currentState;
            return _.find(this.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 = this.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() {
            this.menus.forEach(function (navItem) {
                navItem.isActive = false;
            })
        }
    
        clearActiveStatusWithChildItems() {
            this.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">
                        {
                            this.menus && this.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(connect(mapStateToProps)(Sidebar));

    scss:

    @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 {
        color: $primary-color;
        font-weight: bold;
        border-left: 3px solid $primary-color;
        background-color: $item-active-bg-color;
        a {
          font-weight: bold;
          color: $primary-color;
        }
      }
    
      .nav-item {
        .item-name {
          margin-left: 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;
            }
          }
        }
      }
    }
  • 相关阅读:
    OpenGL ES multithreading and EAGLSharegroup
    NSRange用法(转)
    多测师肖老师_mysql之视图(10.1)
    多测师肖老师__三表(9.1)
    多测师肖老师__多表练习(8.1)
    多测师肖老师__多表讲解(7.9)
    多测师肖老师_mysql之单表练习(7.5)
    多测师肖老师__单表建表和练习(1.8)
    多测师肖老师_mysql之单表和多表题(9.2)
    多测师肖老师___分享杭州面试题
  • 原文地址:https://www.cnblogs.com/Nyan-Workflow-FC/p/9337852.html
Copyright © 2020-2023  润新知