<script> <Menu defaultSelectedKeys={['/home']} //數組類型 讓那個key被選中 這個值不該該寫死,應該根據路徑肯定 defaultOpenKeys={['sub1']} mode="inline" //菜單下拉方式 vertival theme="dark" inlineCollapsed={this.state.collapsed} >
</script>
每一個menu都對應一個路由,因此配對的時候用路徑react
Menu.Item裏的key就用路徑來匹配 由於是惟一的數組
點擊menu.item裏的內容應該進行路由的跳轉 因此用Link包裹起來react-router
優化:不夠靈活app
一個菜單主要包含圖標和文字和key 導航列表應該設置成爲一個配置dom
src/config/menuConfig.js函數
<script> const menuList = [ { title: '首頁', // 菜單標題名稱 key: '/home', // 對應的path icon: 'home', // 圖標名稱 public: true, // 公開的 }, { title: '商品', key: '/products', icon: 'appstore', children: [ // 子菜單列表 { title: '品類管理', key: '/category', icon: 'bars' }, { title: '商品管理', key: '/product', icon: 'tool' }, ] }, { title: '用戶管理', key: '/user', icon: 'user' }, { title: '角色管理', key: '/role', icon: 'safety', }, { title: '圖形圖表', key: '/charts', icon: 'area-chart', children: [ { title: '柱形圖', key: '/charts/bar', icon: 'bar-chart' }, { title: '折線圖', key: '/charts/line', icon: 'line-chart' }, { title: '餅圖', key: '/charts/pie', icon: 'pie-chart' }, ] }, ] export default menuList </script>
根據menuList生成標籤類型,把menu裏的內容顯示出來優化
根據數組數據生成標籤數組this
<script> //根據指定menu數據數組生成<Menu.Item>和SubMenu的數組 //map+函數遞歸 renderMenu = (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> ) } return( <SubMenu key={item.key} title={ <span> <Icon type={item.icon} /> <span>{item.title}</span> </span> } > {this.renderMenu2(item.children)} </SubMenu> ) }) } render() { return ( <div className={styles.leftNav}> <header> <Link to="/" > 後臺系統 </Link> </header> <Menu defaultSelectedKeys={['/home']} // defaultOpenKeys={['sub1']} mode="inline" theme="dark" inlineCollapsed={this.state.collapsed} > {this.renderMenu(menuList)} </Menu> </div> ); } } </script/>
//根據指定menu數據數組生成<Menu.Item>和SubMenu的數組 // reduce+函數遞歸 renderMenu2=(menuList)=>{ //求奇數和 const arr1=[1,2,3,4] arr1.reduce((preTotal,item)=>{ // return preTotal + item //這樣是全部元素的和 必須把當此統計的結果return 變爲下次統計的初始值 return proTotal + (item%2===1?item:0) //返回奇數和 這個是便利回調函數:統計:必須返回當此統計的結果 },0) //0表明的初始總和 }
<script> renderMenu2=(menuList)=>{ // //求奇數和 // const arr1=[1,2,3,4] // arr1.reduce((preTotal,item)=>{ // // return preTotal + item //這樣是全部元素的和 必須把當此統計的結果return 變爲下次統計的初始值 // return proTotal + (item%2===1?item:0) //返回奇數和 這個是便利回調函數:統計:必須返回當此統計的結果 // },0) //0表明的初始總和 return menuList.reduce((pre,item)=>{ //可能向pre添加<Menu.Item></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{ pre.push( <SubMenu key={item.key} title={ <span> <Icon type={item.icon} /> <span>{item.title}</span> </span> } > {this.renderMenu2(item.children)} </SubMenu>) } //多是SubMenu return pre },[]) } </script>
路由器有個模塊組件叫withRouter 可讓組件得到路由方法spa
<script> import { Link,withRouter } from 'react-router-dom' const { SubMenu } = Menu; class leftNav extends Component { state = { } //向外暴露,使用高階組件withRouter()來包裝非路由組件 //新組件向LeftNav傳遞3個特別屬性:history/location/match //結果:leftNav能夠操做路由相關語法了 export default withRouter(leftNav) </script>
<Menu
defaultSelectedKeys={['/home']} //數組類型 讓那個key被選中 這個值不該該寫死,應該根據路徑肯定
<script> //讓子菜單能自動選中 renderMenu2=(menuList)=>{ const path = this.props.location.pathname return menuList.reduce((pre,item)=>{ //可能向pre添加<Menu.Item></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的key是不是我須要的openKey 查找item的全部children中cItem的key,看是否有一個跟請求的path匹配 */ const cItem = item.children.find(cItem=>cItem.key===path) if(cItem){ this.openKey = item.key } pre.push( <SubMenu key={item.key} title={ <span> <Icon type={item.icon} /> <span>{item.title}</span> </span> } > {this.renderMenu2(item.children)} </SubMenu>) } //多是SubMenu return pre },[]) } render() { //由於下方的this.openKey會拿不到值,因該先把子組件渲染出來拿到openKey const menuNode = this.renderMenu2(menuList) //獲得當前請求的路由路徑:這個是路由的能力 const selectKey = this.props.location.pathname //可是this.props.location是undefied props裏沒有location //這是個非路由組件,因此沒有history,location 但咱們須要路由裏面的屬性 //這時候路由組件提供了withRouter return ( <div className={styles.leftNav}> <header> <Link to="/" > 後臺系統 </Link> </header> <Menu defaultSelectedKeys={[selectKey]} //這個值應該根據路徑進行變化,而不是固定的 defaultOpenKeys={[this.openKey]} //沒有這個的時候,路徑爲子菜單的時候,不會展開,看不到,須要請求到子路由的時候讓他自動展開 mode="inline" theme="dark" inlineCollapsed={this.state.collapsed} > {menuNode} </Menu> </div> </script>
優化:從login進入admin會進行兩次rendercode
理由是:login頁面點擊登錄後使用了this.props.history.replace進行跳轉進入‘/ ’,這時候LeftNav組件進行第一次渲染,而後進入Content組件,遇到<Redirect to="/home" />又進行匹配 進行跳轉
這個時候其實要進入App.js裏進行匹配,App.js只有‘/login' 和 ’/ ' ,其實進行的是模糊匹配 ’/home'匹配不到login就會去匹配 '/ '
要設置成精確匹配 使用exact={true} 可是不能使用這個 只用這個 '/home‘就匹配不到
{/**/}
defaultSelectKeys:老是根據據第一次指定的key進行顯示
selectedKeys:老是根據最新指定的key進行顯示 ;因此用這個