# 实现动态面包屑导航
# 完整代码如下
// routes
export const routes: MenuRoute[] = [
{
routeProps: {
path: '/',
element: <App />,
},
children: [
{
routeProps: {
index: true,
element: <IndexPage />
},
title: '首页',
hideInMenu: true,
hasMainLayout: false,
},
{
routeProps: {
path: 'login',
element: <Login />
},
title: '登录',
hideInMenu: true,
hasMainLayout: false,
},
{
routeProps: {
path: 'product-manage',
element: <ProductManage />,
},
title: '商品管理',
icon: 'product',
code: PRODUCT_MANAGE.CODE,
children: [
{
routeProps: {
path: 'create-product',
element: <Product />,
},
title: '创建商品',
code: PRODUCT_MANAGE.CREATE_PRODUCT,
hideInMenu: true
},
{
routeProps: {
path: 'product-detail',
element: <Product />,
},
title: '商品详情',
code: PRODUCT_MANAGE.VIEW_PRODUCT_DETAIL,
hideInMenu: true
},
]
},
{
routeProps: {
path: 'order-manage',
element: <OrderManage />,
},
title: '订单管理',
code: ORDER_MANAGE.CODE,
icon: 'order',
},
{
routeProps: {
path: '*',
element: <IndexPage />
},
hideInMenu: true,
hasMainLayout: false,
},
]
}
]
import { Breadcrumb } from 'antd'
import { useLocation, useNavigate } from 'react-router-dom'
import styles from './breadcrumb.module.scss'
import routes, { MenuRoute } from '@/router'
import classNames from 'classnames'
interface BreadcrumbItem extends MenuRoute {
isLink?: boolean // 是否可点击跳转
}
export default function BreadcrumbPage() {
const location = useLocation()
const navigate = useNavigate()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const flattenRoutes: (arr: MenuRoute[]) => BreadcrumbItem[] = (arr: MenuRoute[]) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
arr.reduce((prev: any[], item: MenuRoute) => {
prev.push(item)
return prev.concat(
Array.isArray(item.children) ? flattenRoutes(item.children) : []
)
}, [])
// 把路由平铺成一维数组
const flattenRouteArr = flattenRoutes(routes)
// 获取路径,截取成数组
const pathArr = location.pathname.substring(1).split('/')
//面包屑子级数组
const breadcrumbItems: BreadcrumbItem[] = []
// 遍历匹配追加到面包屑子级数组
pathArr.forEach(element => {
const menu = flattenRouteArr.find((item: BreadcrumbItem) => item.routeProps.path === element)
if (menu) {
menu.isLink = !!menu.routeProps.element
breadcrumbItems.push(menu)
}
})
// 点击面包屑item
const handleClickItem = (item: BreadcrumbItem) => {
if (!item.isLink) {
return
}
navigate({
pathname: item.fullPath || '/'
})
}
return (<div className={styles.breadcrumbPage}>
当前位置:
<Breadcrumb>
{
breadcrumbItems.map((item: BreadcrumbItem) => <Breadcrumb.Item className={classNames(item.isLink && styles.isLink)} key={item.title} onClick={() => handleClickItem(item)}>{item?.title || '-'}</Breadcrumb.Item>)
}
</Breadcrumb>
</div>)
}
参考文章: