- 定义面包屑list,每次push当前页面,push前校验是否为第一层级,第一层级清除list
- 单页面路由需监听页面刷新,缓存list
import React, { useContext, useEffect, useState } from 'react';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import { useLastLocation } from 'react-router-last-location';
import { findIndex } from 'lodash';
import { Breadcrumb } from '@huohua/luca';
import NativePageJump from '@utils/nativePageJump';
import RouterContext from '@components/Context/RouterContext';
import './style.less';
// 历史记录
let PRE_LIST = [];
// 通过name找到记录
const getBreadcrumbName = ({ routes, location }) => {
return routes.filter(f => {
// 存在动态参数
if (
f?.action?.indexOf(':') !== -1 &&
f?.action?.split('/')?.length === location?.pathname?.split('/')?.length &&
location?.pathname?.startsWith(f?.action?.split(':')?.[0])
) {
return f;
}
return f?.action === location?.pathname;
})?.[0];
};
// 获取面包屑记录
function getBreadcrumb({ routes, location, cache, rootPages }) {
if (location) {
const cacheUrl = `${location?.pathname}${location?.search}`;
const route = getBreadcrumbName({ routes, location });
// 如果当前是二级目录,需要将一级目录手动导入
if (rootPages?.find(item => item?.id === route?.id)) {
const parent = routes?.find(item => item.id === route?.pid);
parent &&
cache.push({
path: parent?.action,
name: parent?.title,
});
}
cache.push({
path: cacheUrl,
name: route?.title,
});
return cache;
}
return [];
}
interface BreadRoutes {
name: string;
path: string;
}
/**
* 面包屑
* @constructor
* 面包屑list 历史路由 + 当前路由
* 需鉴定页面刷新,存储历史路由
* 根目录判断依托于星云菜单配置 二级菜单为页面跳转
* todo 一级目录 未对应直接页面,点击不可跳转 pid为0
* 二级目录 为第一层页面
*/
const Bread = ({ routes, location }) => {
// 获取最后一个地址 - 上个页面地址
const lastLocation: any = useLastLocation();
const router: any = useContext(RouterContext);
// 二级目录
const [rootPages, setRootPages] = useState<any[]>([]);
// 面包屑记录
const [breadRoutes, setBreadRouts] = useState<BreadRoutes[]>([]);
useEffect(() => {
if (!routes?.length) return;
// 二级目录
const packageRoute = routes?.filter(item => item?.pid === 0 && item?.display);
// 根目录 -- 星云返回的二级目录
let _rootPages = [];
packageRoute?.map(item => {
const list = routes?.filter(it => it?.pid === item?.id);
_rootPages = _rootPages.concat(list);
});
setRootPages(_rootPages);
}, [routes]);
// 监听事件处理
const listenReload = () => {
// 设置刷新字段
window.sessionStorage.setItem('BREAD_PAGE_LOAD', '1');
// 存储历史记录(不包含当前页面)
if (PRE_LIST?.length) {
window.sessionStorage.setItem('BREAD_PRE_LIST', JSON.stringify(PRE_LIST));
}
};
// 监听页面刷新
useEffect(() => {
const isReload = window.sessionStorage.getItem('BREAD_PAGE_LOAD');
if (!isReload) window.sessionStorage.setItem('BREAD_PAGE_LOAD', '0');
window.addEventListener('beforeunload', listenReload);
return () => {
window.removeEventListener('beforeunload', listenReload);
};
}, []);
// 跳转地址
useEffect(() => {
if (!routes?.length || !rootPages?.length || !location) return;
// 当前页面是否刷新
const isReload = window.sessionStorage.getItem('BREAD_PAGE_LOAD');
if (!PRE_LIST?.length && isReload === '1') {
// 历史页面
PRE_LIST = JSON.parse(window.sessionStorage.getItem('BREAD_PRE_LIST') || '[]');
window.sessionStorage.setItem('BREAD_PAGE_LOAD', '0');
} else {
// 不刷新 --> PRE_LIST 为上个页面之前的历史,需要通过 lastLocation 合成为历史数据
PRE_LIST = getBreadcrumb({ routes, location: lastLocation, cache: PRE_LIST, rootPages });
}
// 当前页面
let current = [];
// 二级导航清空数据, 并导入一级导航
if (rootPages?.find(item => item?.action === location?.pathname)) {
PRE_LIST = [];
}
// 当前路由
current = getBreadcrumb({ routes, location, cache: current, rootPages });
// 面包屑
const result = [...PRE_LIST, ...current];
// 查找与当前路径相同的第一个路由 并将其从面包屑中去除
const index = findIndex(result || [], {
name: getBreadcrumbName({ routes, location })?.title,
});
index !== result.length - 1 && result.splice(index + 1, result.length);
setBreadRouts(() => result);
}, [location, routes, lastLocation, rootPages]);
if (breadRoutes.length === 0) return null;
const handleJumpPage = url => {
NativePageJump(
{
url,
router,
},
{
isReplace: true,
},
);
};
return (
<Breadcrumb className="bread-crumb" separator=">">
{breadRoutes.map((c, index) => {
return (
<Breadcrumb.Item
className={classNames('crumb', { 'last-crumb': index === breadRoutes?.length - 1 })}
key={`breadcrumb-${index}`}
// 一级目录、当前页皆不可点击跳转
onClick={() => index !== breadRoutes?.length - 1 && index !== 0 && handleJumpPage(c.path)}>
{c?.name}
</Breadcrumb.Item>
);
})}
</Breadcrumb>
);
};
// 导出
export default withRouter(Bread);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。