class LeftNav extends Component {
/*
判断当前登陆用户对 item 是否有权限
*/
hasAuth = (item) => {
const {key, isPublic} = item
const menus = memoryUtils.user.role.menus
const username = memoryUtils.user.username
/*
1. 如果当前用户是 admin
2. 如果当前 item 是公开的
3. 当前用户有此 item 的权限: key 有没有 menus 中
*/
if(username==='admin' || isPublic || menus.indexOf(key)!==-1) {return true} else if(item.children){ // 4. 如果当前用户有此 item 的某个子 item 的权限
return !!item.children.find(child => menus.indexOf(child.key)!==-1)
}
return false
}
/*
根据 menu 的数据数组生成对应的标签数组
使用 map() + 递归调用
*/
getMenuNodes_map = (menuList) => {
return menuList.map(item => {if(!item.children) {
return (<Menu.Item key={item.key}>
<Link to={item.key}>
<Icon type={item.icon}/>
<span>{item.title}</span>
</Link>
</Menu.Item>
)
} else {
return (
<SubMenu
key={item.key}
title={
<span>
<Icon type={item.icon}/>
<span>{item.title}</span>
</span>
}
>
{this.getMenuNodes(item.children)}
</SubMenu>
)
}
})
}
/*
根据 menu 的数据数组生成对应的标签数组
使用 reduce() + 递归调用
*/
getMenuNodes = (menuList) => {
// 得到当前请求的路由路径
const path = this.props.location.pathname
return menuList.reduce((pre, item) => {
// 如果当前用户有 item 对应的权限, 才需要显示对应的菜单项
if (this.hasAuth(item)) {
// 向 pre 添加 <Menu.Item>
if(!item.children) {
pre.push((<Menu.Item key={item.key}>
<Link to={item.key}>
<Icon type={item.icon}/>
<span>{item.title}</span>
</Link>
</Menu.Item>
))
} else {
// 查找一个与当前请求路径匹配的子 Item
const cItem = item.children.find(cItem => path.indexOf(cItem.key)===0)
// 如果存在, 说明当前 item 的子列表需要打开
if (cItem) {this.openKey = item.key}
// 向 pre 添加 <SubMenu>
pre.push((
<SubMenu
key={item.key}
title={
<span>
<Icon type={item.icon}/>
<span>{item.title}</span>
</span>
}
>
{this.getMenuNodes(item.children)}
</SubMenu>
))
}
}
return pre
}, [])
}
/*
在第一次 render()之前执行一次
为第一个 render() 准备数据(必须同步的)
*/
componentWillMount () {
this.menuNodes = this.getMenuNodes(menuList)
}
render() {
// debugger
// 得到当前请求的路由路径
let path = this.props.location.pathname
console.log('render()', path)
if(path.indexOf('/product')===0) { // 当前请求的是商品或其子路由界面
path = '/product'
}
// 得到需要打开菜单项的 key
const openKey = this.openKey
return (
<div className="left-nav">
<Link to='/' className="left-nav-header">
<img src={logo} alt="logo"/>
<h1> 硅谷后台 </h1>
</Link>
<Menu
mode="inline"
theme="dark"
selectedKeys={[path]}
defaultOpenKeys={[openKey]}
>
{this.menuNodes}
</Menu>
</div>
)
}
}
/*
withRouter 高阶组件:
包装非路由组件, 返回一个新的组件
新的组件向非路由组件传递 3 个属性: history/location/match
*/
export default withRouter(LeftNav)