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;
}
}
}
}
}
react: menuService的更多相关文章
- react: navigator
1.page js import React from "react"; import {Link} from "react-router-dom"; impo ...
- react组件的生命周期
写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...
- 十分钟介绍mobx与react
原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...
- RxJS + Redux + React = Amazing!(译一)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...
- React 入门教程
React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...
- 通往全栈工程师的捷径 —— react
腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...
- 2017-1-5 天气雨 React 学习笔记
官方example 中basic-click-counter <script type="text/babel"> var Counter = React.create ...
- RxJS + Redux + React = Amazing!(译二)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...
- React在开发中的常用结构以及功能详解
一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...
随机推荐
- JVM虚拟机—JVM内存
JVM在运行时将数据划分为了5个区域来存储,这5个区域图示如下: 其中方法区和堆对是所有线程共享的内存区域:而java栈.本地方法栈和程序员计数器是运行时线程私有的内存区域. 首先我们熟悉一下一个 J ...
- JS连等赋值的坑
cnblogs标题: JS连等赋值的坑 关于JS连等赋值有个经典的笔试题: var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); ...
- Centos学习笔记2-网络部分
一:修改IP地址:vi /etc/sysconfig/network-scripts/ifcfg-eth0 IPADDR=192.168.80.100 NETMASK=255.255.255.0 GA ...
- iOS学习之数据持久化详解
前言 持久存储是一种非易失性存储,在重启设备时也不会丢失数据.Cocoa框架提供了几种数据持久化机制: 1)属性列表: 2)对象归档: 3)iOS的嵌入式关系数据库SQLite3: 4)Core Da ...
- 安装三大浏览器驱动driver
1.chromedriver 下载地址:https://code.google.com/p/chromedriver/downloads/list 2.Firefox的驱动geckodriver 下载 ...
- Keepalived 服务器状态监测
keepalived简介: keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层.第4层和第5层交换.Keepalived的作用是检测web服务器 ...
- Java中的静态方法是什么?
静态方法是使用公共内存空间的,就是说所有对象都可以直接引用,不需要创建对象再使用该方法. 例如,我创建一个类,里面有一个静态方法: class Test{ public static int z(in ...
- Javascript中call()和apply()的用法 ----1
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...
- 使用 getopt 处理命令行长参数
getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令. getopt 与 getopts 的区别 getopts 是 shell 内建命令, getopt 是一个独立外 ...
- javascript 的dateObj.getTime() 在为C#的获取方式
public string GetTime(DateTime dt) { Int64 retval = 0; DateTime st = new DateTime(1970, 1, 1); TimeS ...