3.左側導航欄

<script>

<Menu
          defaultSelectedKeys={['/home']} //數組類型  讓那個key被選中  這個值不該該寫死,應該根據路徑肯定
          defaultOpenKeys={['sub1']}
          mode="inline"  //菜單下拉方式  vertival
          theme="dark"
          inlineCollapsed={this.state.collapsed}
        >
     
    <Menu.Item key="/home">
            <Link to="/home">
              <Icon type="home" />
              <span>首頁</span>
            </Link>
          </Menu.Item>

          <SubMenu
            key="pro"
            title={
              <span>
                <Icon type="mail" />
                <span>商品</span>
              </span>
            }
          >
            <Menu.Item key="/category">
              <Link to="/category">
                <Icon type="folder-open" />
                <span>品類管理</span>
              </Link>
            </Menu.Item>
            <Menu.Item key="/products">
              <Link to="/products">
                <Icon type="filter" />
                <span>商品管理</span>
              </Link>
            </Menu.Item>
          </SubMenu>
        </Menu>
 
</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

 {menuList.map(item=>(
            <Menu.Item key={item.key}>
            <Link to={item.key}>
              <Icon type={item.icon} />
              <span>{item.title}</span>
            </Link>
          </Menu.Item>
          ))}
<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/>

 

 
 
用reduce方法實現menu
 
 
  //根據指定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被選中  這個值不該該寫死,應該根據路徑肯定
 //獲得當前請求的路由路徑:這個是路由的能力
    const selectKey = this.props.location.pathname  //可是this.props.location是undefied  props裏沒有location
    //這是個非路由組件,因此沒有history,location  但咱們須要路由裏面的屬性
    //這時候路由組件提供了withRouter 
 
<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進行顯示 ;因此用這個

相關文章
相關標籤/搜索