我们先上代码,代码里面都有注释,我是单独写了一个组件,方便使用,在其他页面引入就行了
还使用了官方的Breadcrumb组件
import React, { useEffect, useState } from 'react';
import { Breadcrumb, Button } from 'antd';
import { useLocation, NavLink, useNavigate } from 'react-router-dom';
// 定义面包屑项的类型
interface LocaItem {
path: string;
title: string;
}
interface CustomBreadcrumbProps {
title: string; // 当前页面的标题,动态传递
}
const CustomBreadcrumb: React.FC<CustomBreadcrumbProps> = ({ title }) => {
const navigate = useNavigate();
const location = useLocation();
const [loca, setLoca] = useState<LocaItem[]>([]);
useEffect(() => {
// 获取存储的面包屑数据
const storedLoca = JSON.parse(sessionStorage.getItem('loca') || '[]');
// 创建新面包屑项
const newObject: LocaItem = {
path: location.pathname,
title: title, // 使用传入的 title 作为当前页面的标题
};
// 判断 loca 中是否有相同的 title
const isExist = storedLoca.some((item: LocaItem) => item.title === newObject.title);
// 如果不存在相同的 title,就 push 新对象
if (!isExist) {
storedLoca.push(newObject);
sessionStorage.setItem('loca', JSON.stringify(storedLoca)); // 存储新的面包屑数据
}
setLoca(storedLoca); // 更新组件状态
}, [location.pathname, title]); // 每次路径或标题变化时,更新面包屑
// 删除面包屑项
const handleRemove = (path: string) => {
console.log(location.pathname);
console.log(path);
// 检查路径是否相同
if (location.pathname === path) {
const pathlink = JSON.parse(sessionStorage.getItem('loca') || '[]');
const pathlinkLength = pathlink.length - 1;
if (path === pathlink[pathlinkLength].path) {
const newPath = String(pathlink[pathlinkLength - 1]?.path);
// 延迟跳转,确保状态更新后执行
setTimeout(() => {
navigate(newPath || '/'); // 如果路径为空,跳转到默认页面
}, 0);
} else {
const newPath = String(pathlink[pathlinkLength - 2]?.path);
// 延迟跳转,确保状态更新后执行
setTimeout(() => {
navigate(newPath || '/'); // 如果路径为空,跳转到默认页面
}, 0);
}
}
// 更新面包屑数据
const updatedLoca = loca.filter((item) => item.path !== path);
sessionStorage.setItem('loca', JSON.stringify(updatedLoca)); // 更新 sessionStorage
setLoca(updatedLoca); // 更新状态
};
// 渲染面包屑项
const breadcrumbItems = loca.map((item: LocaItem) => ({
title: (
<span style={
{ display: 'flex', alignItems: 'center', marginLeft: '10px' }}>
<NavLink
to={item.path}
style={({ isActive }) => ({
fontWeight: isActive ? 'bold' : 'normal', // 高亮显示
color: isActive ? '#1890FF' : 'normal', // 当前项文字颜色
backgroundColor: isActive ? '#e6f7ff' : 'normal', // 当前项背景颜色
borderBottom: isActive ? '1px solid #1890FF' : 'normal',
borderRadius: '0',
height: '30px',
lineHeight: '30px',
padding: '0 10px 0 10px',
})}
>
{item.title}
</NavLink>
{/* 关闭按钮 */}
<Button
onClick={() => handleRemove(item.path)} // 点击删除当前面包屑项
disabled={item.title === "首页"} // 禁用“首页”按钮
type="link"
icon={<span style={
{ fontSize: '16px' }}>×</span>}
style={
{
padding: 0,
fontSize: '16px',
display: item.title === "首页" ? 'none' : 'block',
width: '20px',
margin: item.title === "首页" ? '0 5px 0 0' : '0',
}}
/>
</span>
),
}));
return (
<Breadcrumb
style={
{
margin: '16px 0',
height: '30px',
}}
items={breadcrumbItems} // 使用动态生成的面包屑项
separator="" // 去掉默认的斜杠分隔符
itemRender={(route) => {
return (
<span style={
{ marginRight: '10px',whiteSpace:'nowrap' }}>{route.title}</span> // 给每个面包屑项加间距
);
}}
/>
);
};
export default CustomBreadcrumb;
然后在其他页面引入
javascript">import Breadcrumbs from '../../../src/components/Breadcrumb/Breadcrumb';
使用:
title是面包屑的名称,你也可以获取当前路由的title,写个动态的
<Breadcrumbs title="需求管理" />
效果: