- 定义面包屑 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);