Breadcrumb 面包屑
Antd的面包屑组件是一个能够结合路由进行跳转页面的组件,其中对于路由的支持是react-router@3以及react-router@4。
Menu菜单高亮问题
问题描述:ant-design 的 Menu 自带菜单高亮样式。但是,当我们刷新页面时,Menu的高亮样式和伸缩状态会重置。如何解决这个问题呢?
修复目标:当我们刷新网页时,Menu 菜单的高亮样式和伸缩状态可以正常保留,且由当前 url 值所控制。
本篇文章你将学习到以下知识点:
- 使用 react-router-dom(v5) 中相关的 Hooks API;
- 计算属性 useMemo() 的使用;
- 自定义封装 Hooks,实现代码逻辑的封装与复用;
- 使用 ant-design 的 Menu 组件;
- 如果可能,你还能学到更多其它知识。
自定义封装 useMenu()
import { useMemo } from 'react'
import { useLocation } from 'react-router-dom'
import { asyncRoutes } from '@/views'
// 通过useLocation访问当前url,根据url,在routes路由信息中遍历找到对应的key及其父级的key
export function useMenu () {
const { pathname } = useLocation()
// console.log('----pathname', pathname)
// console.log('----asyncRoutes', asyncRoutes)
return useMemo(()=>{
let selectedKey = ''
let openKey = ''
// 用两层for写,更方便地退出循环
asyncRoutes.forEach(ele => {
if (!ele.children) {
if (ele.path === pathname) {
selectedKey = ele.key
}
}
if (ele.children) {
ele.children.forEach(ele2 => {
// console.log('---ele2')
if (ele2.path === pathname) {
selectedKey = ele2.key
openKey = ele.key
// console.log('---ele2')
}
})
}
})
// 坑:Menu高亮要求用 string[] 进行控制
return [selectedKey+'', openKey+'']
}, [pathname])
}
Layout 中 左侧 Sider 组件代码:
import { Link } from 'react-router-dom'
import { useSelector } from 'react-redux'
import { Menu } from 'antd'
import {
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from '@ant-design/icons'
import { useMenu } from '@/hooks'
import logo from '@/assets/logo.png'
function getItem(label, key, icon, children, type) {
return {
key,
icon,
children,
label,
type,
};
}
// 渲染Menu菜单
function createItems (routes) {
const result = routes.map(ele => {
if (ele.path) {
if (!ele.hidden) {
return getItem(
<Link to={ele.path}>{ ele.label }</Link>
,ele.key, ele.icon)
}
} else {
return getItem(
ele.label,
ele.key, ele.icon, createItems(ele.children))
}
})
return result
}
const Logo = props => {
const { collapsed } = props
return (
<div className={!collapsed?'logo2':'logo1'}>
<img src={logo} alt="ght"/>
</div>
)
}
export default props => {
const [selectedKey, openKey] = useMenu()
// console.log('---useMenu', selectedKey, openKey)
const { fixedLogo } = useSelector(state=>state.app)
const { accessRoutes } = useSelector(state=>state.user)
return (
<div className="gh-sider">
{
fixedLogo && <Logo {...props} />
}
{/* 菜单渲染 */}
<Menu
theme="dark"
mode="inline"
selectedKeys={[selectedKey]}
defaultOpenKeys={[openKey]}
items={createItems(accessRoutes)}
/>
</div>
)
}
计算面包屑显示
export function useBreadcrumb () {
const arr = [...asyncRoutes]
const { pathname } = useLocation()
let result = [arr[0]] // 把首页添加面包屑中
// 找二级菜单
if (pathname !== '/dashboard') {
for (let i=0; i<arr.length; i++) {
if (arr[i].children) {
for (let j=0; j<arr[i].children.length; j++) {
if (arr[i].children[j].path === pathname) {
result.push(arr[i])
result.push(arr[i].children[j])
}
}
}
}
}
return result
}
本文含有隐藏内容,请 开通VIP 后查看