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