Ant Design V5 menu导航栏02菜单项随url的变化自动切换

菜单项随url的变化自动切换

基于上一节内容,可以实现点击menu组件中的菜单项,然后跳转到对应的页面,但如果直接在浏览器中通过url访问,就会自动跳转到首页。
这是因为我们在函数组件中初始化了current的值为home。
同时,我们将为新增一个侧边栏做准备。
基于上述两点:

  • 需要首先将子组件内的交互逻辑转移到父组件中,来更好的进行状态管理。
  • 其次,将点击MenuItem的逻辑 和跳转的逻辑分开。

新的内容:useLocation

参看 :https://reactrouter.com/en/6.8.0/hooks/use-location
该hooks返回当前的location对象,通过location.pathname可以得知当前url

// MainLayout.jsx
import { Outlet } from 'react-router-dom'
import { Layout } from 'antd'
import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons'
import { useNavigate,useLocation } from "react-router-dom"
import { useState, useEffect } from 'react'

import HeadBar from '../../components/HeadBar'
import SideBar from '../../components/SideBar'
import { headerStyle, contentStyle, siderStyle, footerStyle } from './layoutStyles.js'

const { Header, Footer, Sider, Content } = Layout
const menuList = [
    {
        label: 'home',
        key: 'home',
        icon: <MailOutlined />,
        sideList: []
    },
    {
        label: 'about',
        key: 'about',
        icon: <AppstoreOutlined />,
        sideList: [
            {
                key: 'aboutMe',
                icon: <AppstoreOutlined />,
                label: 'aboutMe'
            },
            {
                key: 'myReading',
                icon: <MailOutlined />,
                children: [
                    {
                        key: 'englishBooks',
                        icon: <AppstoreOutlined />,
                        label: 'englishBooks'
                    },
                    {
                        key: 'chineseBooks',
                        icon: <SettingOutlined />,
                        label: 'chineseBooks'
                    },
                ],
                label: 'myReading'
            }
        ]
    }
]

function MainLayout() {
    /** 
     * 整个页面的逻辑分两块:
     * 当通过url访问页面时,menu的默认选中根据url走
     * 当点击menu item 的时候,根据点击的item 跳转页面。
     */ 
    const navigate = useNavigate()
    const location = useLocation()
    const [headBarCurrent,changeHeadBarCurrent] = useState('')
    const [clickChange,changeClickChange] = useState(null)

    useEffect(()=>{ // 当location发生变化时 需要更改菜单选中值
        const path = location.pathname
        menuList.map(e=>{
            const key = e.key
            if(path.indexOf(key) !== -1){
                changeHeadBarCurrent(key)
            }
        })
    },[location])

    useEffect(()=>{ // 在菜单点击事件发生时
        if(clickChange){ // 跳转页面
            navigate(clickChange)
        }
    },[clickChange])

    const onHeadBarClick = (e) => { // 当顶部导航栏触发点击的时候 需要更新两个值
        changeHeadBarCurrent(e.key) // 告知菜单选中值发生了变化
        const url = '/' + e.key
        changeClickChange(url) // 告知触发了菜单点击事件 需要跳转页面了
    }

    return (
        <div>
            <Layout>
                <Header style={headerStyle}><HeadBar menuList={menuList} current={headBarCurrent} onClick={onHeadBarClick} /></Header>
                <Layout>
                    <Layout>
                        <Content style={contentStyle}>
                            <Outlet />
                        </Content>
                        <Footer style={footerStyle}>footer</Footer>
                    </Layout>
                </Layout>
            </Layout>
        </div>
    )
}

export default MainLayout
// HeadBar.jsx
import { Menu } from 'antd'

function HeadBar(props) {
    return (
        <Menu onClick={props.onClick} selectedKeys={props.current} mode="horizontal" items={props.menuList} />
    )
}

export default HeadBar

项目各依赖的版本:
“antd”: “^5.1.7”,
“react”: “^18.2.0”,
“react-dom”: “^18.2.0”,
“react-router-dom”: “^6.8.0”,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值