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 ...
随机推荐
- Windows Server 2012 云硬盘如何挂载
那么首先科普一下,云服务器的数据盘(也就是我们买的云硬盘)默认是脱机状态,不自动挂载的.下面来教大家win2012环境如何挂载硬盘,其实和03.08的大同小异就是入口不同了. 点击“工具”中的“计 ...
- StringBuilder String string.Concat 字符串拼接速度
首先看测试代码: public class StringSpeedTest { "; public string StringAdd(int count) { string str = st ...
- beego——静态文件
Go 语言内部其实已经提供了 http.ServeFile,通过这个函数可以实现静态文件的服务. beego 针对这个功能进行了一层封装,通过下面的方式进行静态文件注册: beego.SetStati ...
- python中json怎么转换成字典
json的标准格式:要求必须 只能使用双引号作为键 或者 值的边界符号,不能使用单引号,而且“键”必须使用边界符(双引号)
- Java8中时间日期库的20个常用使用示例
除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务示例来学习如何使用Java 8的这套API.Java对日期, ...
- 对于C++指针的详细理解
(1)每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址. eg: int var1; &var1 表示var1的地址 ...
- 一般处理程序中 C#中对象转化为Json对象
namespace: Newtonsoft.Json; context.Response.ContentType = "application/text"; 注:这里为什么不是 J ...
- Django学习笔记之模板渲染、模板语言、simple_tag、母版子版、静态配置文件
一.首先我们用PyCharm来创建一个Django项目 终端命令:django-admin startproject sitename 图形创建: 这样一个Django项目就创建完成了,上面可以看 ...
- 【Flask】Flask Session操作
### session:1. session的基本概念:session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个 ...
- Hibernate的一级缓存、二级缓存和查询缓存。
Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体.修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除 ...