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都对应一个路由,所以配对的时候用路径

Menu.Item里的key就用路径来匹配  因为是唯一的

点击menu.item里的内容应该进行路由的跳转   所以用Link包裹起来

优化:不够灵活

一个菜单主要包含图标和文字和key   导航列表应该设置成为一个配置

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里的内容显示出来

根据数组数据生成标签数组

{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   可以让组件获得路由方法

<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会进行两次render

理由是:login页面点击登陆后使用了this.props.history.replace进行跳转进入‘/ ’,这时候LeftNav组件进行第一次渲染,然后进入Content组件,遇到<Redirect to="/home" />又进行匹配 进行跳转

这个时候其实要进入App.js里进行匹配,App.js只有‘/login‘ 和 ’/ ‘  ,其实进行的是模糊匹配   ’/home‘匹配不到login就会去匹配 ‘/ ‘

要设置成精确匹配  使用exact={true}  但是不能使用这个 只用这个 ‘/home‘就匹配不到

{/**/}

defaultSelectKeys:总是根据据第一次指定的key进行显示

selectedKeys:总是根据最新指定的key进行显示 ;所以用这个

原文地址:https://www.cnblogs.com/lucy-xyy/p/11831107.html

时间: 2024-07-29 13:44:22

3.左侧导航栏的相关文章

CI框架后台添加左侧导航栏出现的一系列问题

后台在数据库中添加了一个栏目.但是但点击这个新添加的栏目之后,却发现左侧的导航栏没有了,,为什么呢. 注意CI框架下在shared/libraries/Acl.php这个文件,(后台权限控制类) 里边有一个show_left_menus()方法,这个方法主要是用来过滤左侧导航栏的功能.在这里边添加你新添加的导航, 发现是不是ok了,,耗费大量人力物力,终于好了..

MFC office2007风格设置左侧导航栏 [转]

当基础的框架搭好以后,我想为其添加一个左侧导航栏,过程如下:在框架类的头文件添加一个导航栏参数: CMFCOutlookBar m_navigation; 为了完善功能,在导航栏里面我添加了一个CTreeCtrl控件 CTreeCtrl m_treectrl; 并且创建一个函数创建导航栏,并关联CTreeCtrl控件,函数原型如下: bool CreateNavigationBar(CMFCOutlookBar& bar, UINT uiID, int nInitialWidth, CTreeC

chrome 网页 左侧导航栏不展开

chrome 网页 左侧导航栏不展开 现象 代码 <li class="one"> <a href="#"><i class="fa fa-sitemap"></i> <span class="nav-label">菜单 </span><span class="fa arrow"></span></a>

使用jsonp形式跨域访问实现电商平台的左侧导航栏

电商平台有个具备的左侧商品类目的导航栏的结构. 通过jsonp跨域访问电商平台的后台管理系统商品分类.(主要实现后台Java代码) 实现基本步骤: 1.在后台管理系统中准备相应的json数据. 1 /** 2 * 前台需要的类目json数据 3 * @author Administrator 4 * 5 */ 6 public class ItemCatResult { 7 @JsonProperty("data") 8 private List<ItemCatData>

简单的jquery左侧导航栏和页面选中效果

这里是要实现导航的左侧并选中的,此功能需引用jquery 效果: 左侧导航 <div class="box"> <ul class="menu"> <li class="level1"> <a href="#none" rel="external nofollow">衬衫</a> <ul class="level2">

夺命雷公狗jquery---33高仿hao123左侧导航栏

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> html,body { margin:0; padding:0; height:100%; } div.menu { width:46px; height:100%; background-color

uni-app中实现左侧导航栏效果

HTML: 1 <view class="list"> 2 <!-- 一级 --> 3 <scroll-view class="list-left" scroll-y :style="'height:'+height+'px'"> 4 <view v-if="dataList.length>0" class="list-nav" @click="ca

左侧导航滚动监听

代码来自潭州java免费视频教程 <!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>左侧导航栏</title

2016/7/20 1:18:29 PyQT5 炫酷的左侧导航效果

2016/7/20 1:18:29  完整code from PyQt5.QtWidgets import (QApplication, QWidget, QHBoxLayout, QTreeWidget, QTreeWidgetItem, QGroupBox) from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtCore import QSize class Bar_Navigation(QWidget): def __init__(self