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;
}
}
}
}
}

react: menuService的更多相关文章

  1. react: navigator

    1.page js import React from "react"; import {Link} from "react-router-dom"; impo ...

  2. react组件的生命周期

    写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...

  3. 十分钟介绍mobx与react

    原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...

  4. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  5. React 入门教程

    React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...

  6. 通往全栈工程师的捷径 —— react

    腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...

  7. 2017-1-5 天气雨 React 学习笔记

    官方example 中basic-click-counter <script type="text/babel"> var Counter = React.create ...

  8. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

  9. React在开发中的常用结构以及功能详解

    一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...

随机推荐

  1. 从SNE到t-SNE再到LargeVis

    http://bindog.github.io/blog/2016/06/04/from-sne-to-tsne-to-largevis/

  2. WebService SOAP WSDL UDDI 使用php的curl、PHP5的SoapClient实现同步

    一.基本名词 WebService: WebService是一种跨编程语言和跨操作系统平台的远程调用技术.不同系统,不同语言的数据交换方法都是不同的,这就导致在不同系统,不同语言之间传递数据很麻烦,基 ...

  3. 第二课客户端链接Linux系统

    使用Putty客户端软件连接Linux主机 使用rpm –qa | grep ssh命令查看是否已经安装ssh服务,如下图是已经安装了ssh服务,如果未列出相关的openssh那么代表未安装这时候就需 ...

  4. [MySQL] 实现树形的遍历(关于多级菜单栏以及多级上下部门的查询问题)

    前言:         关于多级别菜单栏或者权限系统中部门上下级的树形遍历,oracle中有connect by来实现,MySQL没有这样的便捷途径,所以MySQL遍历数据表是我们经常会遇到的头痛问题 ...

  5. Linux命令(6/28)——declare/typeset命令

    declare 与 typeset 命令是bash的内建命令,两者是完全一样的,用来声明shell变量,设置变量的属性. declare命令(别名typeset)属shell内建命令,用于申明shel ...

  6. mount、umount、fuser命令使用小结

    mount -t cifs -o username=administrator,password=xxxxx //192.168.11.17/Data/ /mnt/databak/之后想卸载挂载目录, ...

  7. 【Flask】Flask Session操作

    ### session:1. session的基本概念:session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个 ...

  8. 基于SSM的单点登陆05

    springmvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  9. 20162326 《Java程序设计》第3周学习总结

    20162326 <Java程序设计>第3周学习总结 教材学习内容总结 这周我通过课堂学习了VIM的列编辑crtl+v,shift+i shift+a·分别是左侧插入和右侧插入.还学习了使 ...

  10. 如何自定义echarts 线性图的选择事件

    最近在做公司的数据大盘,要用到图表显示,echarts研二的时候有用过,我就决定用它了. 这里用到一个可以同时显示多条曲线的line-charts,基本样子如下: 看到这个画红色圈圈的地方了吗??? ...