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