{...}"; 2. Set by "handleSelectkeys(e){...}" Selected state; 3. Use "oli.push( {...}"; 2. Set by "handleSelectkeys(e){...}" Selected state; 3. Use "oli.push(

Home  >  Article  >  Web Front-end  >  How to implement three-level menu in react

How to implement three-level menu in react

藏色散人
藏色散人Original
2023-01-19 10:59:20829browse

React method to implement a three-level menu: 1. The method to create and expand the three-level parent menu is "onOpenChange = (openKeys) => {...}"; 2. Through "handleSelectkeys(e) {...}" to set the selected state; 3. Generate the sidebar through "oli.push(

How to implement three-level menu in react

The operating environment of this tutorial: Windows 10 system, react version 18.0.0, Dell G3 computer.

How to implement a three-level menu in react?

react antd implements only expanding the sidebar of a parent menu bar (three-level menu bar)

Encountered at work One requirement is that the three-level sidebar can only expand a parent menu bar to keep the page simple and improve the user experience. I also searched online for a long time and found nothing that fully met the requirements, so I combined other people's own and wrote one... .

How to expand the three-level parent menu

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] : [],
                });
            }            
        }
    }</p>
<p><strong>Set the selected state</strong></p>
<pre class="brush:php;toolbar:false"> 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
             }); 
        }       
    }

Generate the side Column

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] : &#39;&#39;
                                        }
                                    }
                                    
                                    } >
                                    {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:&#39;&#39;
                                }
                            }
                            } >
                            {data[i].iconCls && <Icon type={data[i].iconCls} />}
                            <span>{data[i].text}</span>
                        </Link>
                    </Menu.Item>
                )
            }
        }

Sidebar component Menu.js All code

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 {
        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] : &#39;&#39;
                                        }
                                    }
                                    
                                    } >
                                    {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:&#39;&#39;
                                }
                            }
                            } >
                            {data[i].iconCls && <Icon type={data[i].iconCls} />}
                            <span>{data[i].text}</span>
                        </Link>
                    </Menu.Item>
                )
            }
        }
        return (
            
                {html}
            
        )
    }}export default withRouter(Menus);

Sidebar data 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>
    )
  }}```

Recommended learning: "react video tutorial"

The above is the detailed content of How to implement three-level menu in react. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn