diff --git a/src/components/PageHeaderWrapper/Breadcrumb.tsx b/src/components/PageHeaderWrapper/Breadcrumb.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a099d88180c96893a560d97d9fc0289e1e73b070 --- /dev/null +++ b/src/components/PageHeaderWrapper/Breadcrumb.tsx @@ -0,0 +1,135 @@ +import React from 'react'; +import pathToRegexp from 'path-to-regexp'; +import Link from 'umi/link'; +import { FormattedMessage } from 'umi-plugin-react/locale'; +import { urlToList } from '../_utils/pathTools'; +import { PageHeaderWrapperProps } from '.'; +import { MenuDataItem } from '../SiderMenu'; +import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/lib/breadcrumb'; + +type BreadcrumbProps = PageHeaderWrapperProps; + +// 渲染Breadcrumb 子节点 +// Render the Breadcrumb child node +const itemRender: AntdBreadcrumbProps['itemRender'] = (route, params, routes, paths) => { + const last = routes.indexOf(route) === routes.length - 1; + return last || !route.component ? ( + {route.breadcrumbName} + ) : ( + {route.breadcrumbName} + ); +}; + +const renderItemLocal = (item: MenuDataItem): React.ReactNode => { + if (item.locale) { + return ; + } + return item.name; +}; + +export const getBreadcrumb = ( + breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'], + url: string, +): MenuDataItem => { + if (!breadcrumbNameMap) { + return { + path: '', + }; + } + let breadcrumb = breadcrumbNameMap[url]; + if (!breadcrumb) { + Object.keys(breadcrumbNameMap).forEach(item => { + if (pathToRegexp(item).test(url)) { + breadcrumb = breadcrumbNameMap[item]; + } + }); + } + return breadcrumb || { path: '' }; +}; + +export const getBreadcrumbProps = (props: BreadcrumbProps): PageHeaderWrapperProps => { + const { location, breadcrumbNameMap } = props; + return { + location, + breadcrumbNameMap, + }; +}; + +// Generated according to props +const conversionFromProps = (props: BreadcrumbProps): AntdBreadcrumbProps['routes'] => { + const { breadcrumbList = [] } = props; + return breadcrumbList + .map(item => { + const { title, href } = item; + return { + path: href, + breadcrumbName: title, + }; + }) + .filter(item => item.path); +}; + +const conversionFromLocation = ( + routerLocation: PageHeaderWrapperProps['location'], + breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'], + props: BreadcrumbProps, +): AntdBreadcrumbProps['routes'] => { + if (!routerLocation) { + return []; + } + const { home } = props; + // Convert the url to an array + const pathSnippets = urlToList(routerLocation.pathname); + // Loop data mosaic routing + const extraBreadcrumbItems: AntdBreadcrumbProps['routes'] = pathSnippets + .map(url => { + const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); + if (currentBreadcrumb.inherited) { + return { path: '', breadcrumbName: '' }; + } + const name = renderItemLocal(currentBreadcrumb); + const { hideInBreadcrumb } = currentBreadcrumb; + return name && !hideInBreadcrumb + ? { + path: url, + breadcrumbName: name, + } + : { path: '', breadcrumbName: '' }; + }) + .filter(item => item && item.path); + // Add home breadcrumbs to your head if defined + if (home) { + extraBreadcrumbItems.unshift({ + path: '/', + breadcrumbName: home, + }); + } + return extraBreadcrumbItems; +}; + +/** + * 将参数转化为面包屑 + * Convert parameters into breadcrumbs + */ +export const conversionBreadcrumbList = (props: BreadcrumbProps): AntdBreadcrumbProps => { + const { breadcrumbList } = props; + const { location, breadcrumbNameMap } = getBreadcrumbProps(props); + if (breadcrumbList && breadcrumbList.length) { + return { + routes: conversionFromProps(props), + itemRender, + }; + } + + // 根据 location 生成 面包屑 + // Generate breadcrumbs based on location + if (location && location.pathname) { + return { + routes: conversionFromLocation(location, breadcrumbNameMap, props), + itemRender, + }; + } + return { + routes: [], + }; +}; diff --git a/src/components/PageHeaderWrapper/breadcrumb.tsx b/src/components/PageHeaderWrapper/breadcrumb.tsx index fcaa3b55c9bace56578d9b38ed9bf54fd12d068a..a099d88180c96893a560d97d9fc0289e1e73b070 100644 --- a/src/components/PageHeaderWrapper/breadcrumb.tsx +++ b/src/components/PageHeaderWrapper/breadcrumb.tsx @@ -3,7 +3,7 @@ import pathToRegexp from 'path-to-regexp'; import Link from 'umi/link'; import { FormattedMessage } from 'umi-plugin-react/locale'; import { urlToList } from '../_utils/pathTools'; -import { PageHeaderWrapperProps } from './'; +import { PageHeaderWrapperProps } from '.'; import { MenuDataItem } from '../SiderMenu'; import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/lib/breadcrumb'; diff --git a/src/components/PageHeaderWrapper/index.tsx b/src/components/PageHeaderWrapper/index.tsx index 40b9c88f68953d4de4a4a1f18b310f466d6dee01..367f052a4e83546215f4473df0449d3de0efbed1 100644 --- a/src/components/PageHeaderWrapper/index.tsx +++ b/src/components/PageHeaderWrapper/index.tsx @@ -7,7 +7,7 @@ import GridContent from './GridContent'; import ConnectState from '@/models/connect'; import { ContentWidth } from 'config/defaultSettings'; import styles from './index.less'; -import { conversionBreadcrumbList } from './breadcrumb'; +import { conversionBreadcrumbList } from './Breadcrumb'; import { MenuDataItem } from '../SiderMenu'; import * as H from 'history'; @@ -81,7 +81,18 @@ class PageHeaderWrapper extends React.Component { extraContent, ...restProps } = this.mergePropsAndChildren(); - if (!title && !content) { + let pageTitle = title; + const breadcrumb = conversionBreadcrumbList({ + ...restProps, + home: , + }); + if (!title && breadcrumb.routes) { + const router = breadcrumb.routes[breadcrumb.routes.length - 1]; + if (router) { + pageTitle = router.breadcrumbName; + } + } + if (!pageTitle && !content) { return; } return ( @@ -93,14 +104,11 @@ class PageHeaderWrapper extends React.Component { marginBottom: 0, }} > - {title} + {pageTitle} } {...restProps} - breadcrumb={conversionBreadcrumbList({ - ...restProps, - home: , - })} + breadcrumb={breadcrumb} className={styles.pageHeader} footer={renderFooter(restProps)} > @@ -117,10 +125,9 @@ class PageHeaderWrapper extends React.Component { ); }; render() { - const { children, top } = this.mergePropsAndChildren(); + const { children } = this.mergePropsAndChildren(); return (
- {top} {this.renderPageHeader()} {children ? (