加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、容器安全、数据加密、云日志、云数据迁移!
当前位置: 首页 > 教程 > 正文

react如何完美实现三级菜单

发布时间:2023-07-17 11:30:21 所属栏目:教程 来源:未知
导读:   这篇文章主要讲解了“react如何实现三级菜单”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何实现三级菜
  这篇文章主要讲解了“react如何实现三级菜单”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何实现三级菜单”吧!
 
  react实现三级菜单的方法:1、创建展开三级父级菜单的方法为“onOpenChange = (openKeys) => {...}”;2、通过“handleSelectkeys(e){...}”设置选中状态;3、通过“oli.push(<Menu.Item key={...})实现生成侧边栏即可。
 
  react + antd实现只展开一个父级菜单栏的侧边栏(三级菜单栏)
 
  展开三级父级菜单的方法
 
  onOpenChange = (openKeys) => {
 
          const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1);
 
          let openList;
 
          if(this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
 
              if(latestOpenKey&&latestOpenKey.length===3){
 
                  openList = this.state.openKeys.filter((e)=>{
 
                      return e.length!==3;
 
                  })
 
                  this.setState({
 
                      openKeys:openList                });
 
              }else{
 
                  this.setState({
 
                      openKeys:openKeys                });
 
              }           
 
          }else{
 
              if(latestOpenKey&&latestOpenKey.length===3){
 
                  openList = this.state.openKeys.filter((e)=>{
 
                      return e.length!==3;
 
                  })
 
                  openList.push(latestOpenKey);
 
                  this.setState({
 
                      openKeys:openList[1] ? openList : [openList[0],openList[2]]
 
                  });
 
              }else{
 
                  this.setState({
 
                      openKeys: latestOpenKey ? [latestOpenKey] : [],
 
                  });
 
              }            
 
          }
 
      }
 
  设置选中状态
 
   handleSelectkeys(e){
 
          if(this.state.isShow){
 
              this.setState({
 
                  selectedKey:e.key,
 
                  openKeys:e.keyPath[length] == 3  ? [e.keyPath[2],e.keyPath[1]] : [e.keyPath[0]],
 
                  isShow:true
 
               });
 
          }       
 
      }
 
  生成侧边栏
 
  const data = this.props.list;
 
          var html = [];
 
          for(var i=0;i<data.length;i++){
 
              if(data[i].children){
 
                  var li = []
 
                  for(var j=0;j<data[i].children.length;j++){
 
                      var liData = data[i].children[j];
 
                      if(liData.children){
 
                          var oli = [];
 
                          for(var k=0;k<liData.children.length;k++){
 
                              oli.push(
 
                                  <Menu.Item key={liData.children[k].url}>
 
                                      <Link to={
 
                                          {
 
                                              pathname:liData.children[k].url,
 
                                              state:{//三级菜单下传openKeys传两个值,展开两级
 
                                                  parent:this.state.openKeys[0],
 
                                                  child:this.state.openKeys[1]
 
                                              }
 
                                          }
 
                                      }>
 
                                          <span>{liData.children[k].text}</span>
 
                                      </Link>
 
                                  </Menu.Item>
 
                              )
 
                          }
 
                          var oul = <SubMenu key={liData.id} title={<span>{liData.iconCls && <Icon type={liData.iconCls} />}<span>{liData.text}</span></span>}>{oli}</SubMenu>;
 
                          li.push(oul);
 
                      }else{
 
                          li.push(
 
                              <Menu.Item key={liData.url}>
 
                                  <Link to={
 
                                      {
 
                                          pathname:liData.url,
 
                                          state:{//二级菜单下openKeys传一个值,展开一级
 
                                              parent:this.state.openKeys[0],
 
                                              // child:this.state.openKeys[1] ? this.state.openKeys[1] : ''
 
                                          }
 
                                      }
 
                                      
 
                                      } >
 
                                      {liData.iconCls && <Icon type={liData.iconCls} />}
 
                                      <span>{liData.text}</span>
 
                                  </Link>
 
                              </Menu.Item>
 
                          );
 
                      }
 
                  }
 
                  var ul = <SubMenu key={data[i].id} title={<span>{data[i].iconCls && <Icon type={data[i].iconCls} />}<span>{data[i].text}</span></span>}>{li}</SubMenu>;
 
                  html.push(ul);
 
              }else{
 
                  html.push(
 
                      <Menu.Item key={data[i].url}>
 
                          <Link to={                           
 
                              {
 
                                  pathname:data[i].url,
 
                                  state:{//一级菜单下传空值,不展开菜单栏
 
                                      parent:''
 
                                  }
 
                              }
 
                              } >
 
                              {data[i].iconCls && <Icon type={data[i].iconCls} />}
 
                              <span>{data[i].text}</span>
 
                          </Link>
 
                      </Menu.Item>
 
                  )
 
              }
 
          }
 
  侧边栏组件Menu.js 全部代码
 
  import React from 'react'import { Menu,Icon } from 'antd';import {Link,withRouter} from 'react-router-dom'const { SubMenu } = Menu;
 
   class Menus extends React.Component{
 
      constructor(props){
 
          super(props)
 
          this.state={
 
              openKeys:['1','100'],
 
              rootSubmenuKeys:[],
 
              selectedKeys:[this.props.history.location.pathname], //选中
 
              isShow:false //判断是否已经展开,如已展开停止重新赋值避免重新渲染和关系菜单         
 
          }
 
          this.handleSelectkeys = this.handleSelectkeys.bind(this)
 
      }
 
      UNSAFE_componentWillMount(){
 
          if(this.props.location.state){
 
              this.setState({
 
                  openKeys:[this.props.location.state.parent,this.props.location.state.child ? this.props.location.state.child : '']
 
              })           
 
          }
 
            
 
        }
 
      componentDidMount(props,nextProps){
 
          var data = this.props.list;
 
          for(var i=0;i<data.length;i++){
 
              if(data[i].children){
 
                  for(var j=0;j<data[i].children.length;j++){
 
                      var liData = data[i].children[j];
 
                      if(liData.children){
 
                          this.state.rootSubmenuKeys.push(liData.id+"");
 
                      }
 
                  }
 
                  this.state.rootSubmenuKeys.push(data[i].id+"");
 
              }
 
          }
 
          // 刷新菜单更新默认状态
 
          const { pathname } = this.props.history.location;
 
          const rank = pathname.split('/')
 
          switch (rank.length) {
 
            case 2 :  //一级目录
 
              this.setState({
 
                selectedKeys: [pathname]
 
              })
 
              break;
 
            case 5 : //三级目录,要展开两个subMenu
 
              this.setState({
 
                selectedKeys: [pathname],             
 
              })
 
              break;
 
            default :
 
              this.setState({
 
                selectedKeys: [pathname],
 
              })
 
          }
 
         
 
          // 浏览器前进后退按钮更新菜单状态
 
          if (window.history && window.history.pushState) {
 
              window.onpopstate = function () {
 
                  window.location.reload(true); //刷新页面
 
              };
 
          }
 
      }
 
      handleSelectkeys(e){
 
          if(this.state.isShow){
 
              this.setState({
 
                  selectedKey:e.key,
 
                  openKeys:e.keyPath[length] == 3  ? [e.keyPath[2],e.keyPath[1]] : [e.keyPath[0]],
 
                  isShow:true
 
               });
 
          }       
 
      }
 
      onOpenChange = (openKeys) => {
 
          const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1);
 
          let openList;
 
          if(this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
 
              if(latestOpenKey&&latestOpenKey.length===3){
 
                  openList = this.state.openKeys.filter((e)=>{
 
                      return e.length!==3;
 
                  })
 
                  this.setState({
 
                      openKeys:openList                });
 
              }else{
 
                  this.setState({
 
                      openKeys:openKeys                });
 
              }           
 
          }else{
 
              if(latestOpenKey&&latestOpenKey.length===3){
 
                  openList = this.state.openKeys.filter((e)=>{
 
                      return e.length!==3;
 
                  })
 
                  openList.push(latestOpenKey);
 
                  this.setState({
 
                      openKeys:openList[1] ? openList : [openList[0],openList[2]]
 
                  });
 
              }else{
 
                  this.setState({
 
                      openKeys: latestOpenKey ? [latestOpenKey] : [],
 
                  });
 
              }            
 
          }
 
      }
 
      render(){
 
          const data = this.props.list;
 
          var html = [];
 
          for(var i=0;i<data.length;i++){
 
              if(data[i].children){
 
                  var li = []
 
                  for(var j=0;j<data[i].children.length;j++){
 
                      var liData = data[i].children[j];
 
                      if(liData.children){
 
                          var oli = [];
 
                          for(var k=0;k<liData.children.length;k++){
 
                              oli.push(
 
                                  <Menu.Item key={liData.children[k].url}>
 
                                      <Link to={
 
                                          {
 
                                              pathname:liData.children[k].url,
 
                                              state:{//三级菜单下传openKeys传两个值,展开两级
 
                                                  parent:this.state.openKeys[0],
 
                                                  child:this.state.openKeys[1]
 
                                              }
 
                                          }
 
                                      }>
 
                                          <span>{liData.children[k].text}</span>
 
                                      </Link>
 
                                  </Menu.Item>
 
                              )
 
                          }
 
                          var oul = <SubMenu key={liData.id} title={<span>{liData.iconCls && <Icon type={liData.iconCls} />}<span>{liData.text}</span></span>}>{oli}</SubMenu>;
 
                          li.push(oul);
 
                      }else{
 
                          li.push(
 
                              <Menu.Item key={liData.url}>
 
                                  <Link to={
 
                                      {
 
                                          pathname:liData.url,
 
                                          state:{//二级菜单下openKeys传一个值,展开一级
 
                                              parent:this.state.openKeys[0],
 
                                              // child:this.state.openKeys[1] ? this.state.openKeys[1] : ''
 
                                          }
 
                                      }
 
                                      
 
                                      } >
 
                                      {liData.iconCls && <Icon type={liData.iconCls} />}
 
                                      <span>{liData.text}</span>
 
                                  </Link>
 
                              </Menu.Item>
 
                          );
 
                      }
 
                  }
 
                  var ul = <SubMenu key={data[i].id} title={<span>{data[i].iconCls && <Icon type={data[i].iconCls} />}<span>{data[i].text}</span></span>}>{li}</SubMenu>;
 
                  html.push(ul);
 
              }else{
 
                  html.push(
 
                      <Menu.Item key={data[i].url}>
 
                          <Link to={                           
 
                              {
 
                                  pathname:data[i].url,
 
                                  state:{//一级菜单下传空值,不展开菜单栏
 
                                      parent:''
 
                                  }
 
                              }
 
                              } >
 
                              {data[i].iconCls && <Icon type={data[i].iconCls} />}
 
                              <span>{data[i].text}</span>
 
                          </Link>
 
                      </Menu.Item>
 
                  )
 
              }
 
          }
 
          return (
 
              <Menu
 
                  openKeys={this.state.openKeys}
 
                  selectedKeys={[this.props.history.location.pathname]}
 
                  onClick={this.handleSelectkeys}
 
                  onOpenChange={this.onOpenChange}
 
                  mode="inline"
 
                  theme="dark"
 
                  collapsed={this.state.collapsed}>
 
                  {html}
 
              </Menu>
 
          )
 
      }}export default withRouter(Menus);
 
  侧边栏数据 menu.js
 
  const list = [
 
    {
 
        "id":1,
 
        "text":"检查清单",
 
        "state":"closed",
 
        "iconCls":"home",
 
        "children":[
 
            {
 
                "id":100,
 
                "text":"按月检查",
 
                "checked":false,
 
                "state":"closed",
 
                "iconCls":"",
 
                "url":"/platform/check/month"
 
            },
 
            {
 
                "id":101,
 
                "text":"按年检查",
 
                "checked":false,
 
                "state":"closed",
 
                "iconCls":"",
 
                "url":"/platform/check/year"
 
            }
 
        ]   
 
    },
 
    {
 
        "id":2,
 
        "text":"数据预览导出",
 
        "iconCls":"laptop",
 
        "state":"closed",
 
        "checked":true,
 
        "children":[
 
            {
 
                "id":200,
 
                "text":"做的书",
 
                "iconCls":"",
 
                "state":"closed",
 
                "checked":true,
 
                "children":[
 
                    {
 
                        "id":20001,
 
                        "text":"2018做的书",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/makeBook/2018"
 
                    },
 
                    {
 
                        "id":20002,
 
                        "text":"2019做的书",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/makeBook/2019"
 
                    },
 
                    {
 
                        "id":20003,
 
                        "text":"2020做的书",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/makeBook/2020"
 
                    }
 
                ]
 
            },
 
            {
 
                "id":201,
 
                "text":"财务收入",
 
                "iconCls":"",
 
                "state":"closed",
 
                "checked":true,
 
                "children":[
 
                    {
 
                        "id":20101,
 
                        "text":"2018财务收入",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/GMV/2018"
 
                    },
 
                    {
 
                        "id":20102,
 
                        "text":"2019财务收入",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/GMV/2019"
 
                    },
 
                    {
 
                        "id":20103,
 
                        "text":"2020财务收入",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/GMV/2020"
 
                    },
 
                ]
 
            },
 
            {
 
                "id":202,
 
                "text":"财务支出",
 
                "iconCls":"",
 
                "state":"closed",
 
                "checked":true,
 
                "children":[
 
                    {
 
                        "id":20201,
 
                        "text":"2018财务支出",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/expend/2018"
 
                    },
 
                    {
 
                        "id":20202,
 
                        "text":"2019财务支出",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/expend/2019"
 
                    },
 
                    {
 
                        "id":20203,
 
                        "text":"2020财务支出",
 
                        "iconCls":" ",
 
                        "url":"/platform/export/expend/2020"
 
                    },
 
                ]
 
            },
 
           ]
 
    },
 
   ]class SiderNav extends React.Component {
 
    render() {
 
      return (   
 
        <Sider  width={230}  breakpoint  className="AdminSider">
 
            <Menus list={list} />
 
        </Sider>
 
      )
 
    }}```
 

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章