Commit 231e725a authored by 陈帅's avatar 陈帅

add hiddenBreadcrumb props in PageHeader

parent 85f46650
import React, { PureComponent, createElement } from 'react';
import pathToRegexp from 'path-to-regexp';
import { Breadcrumb } from 'antd';
import styles from './index.less';
import { urlToList } from '../_utils/pathTools';
export const getBreadcrumb = (breadcrumbNameMap, url) => {
let breadcrumb = breadcrumbNameMap[url];
if (!breadcrumb) {
Object.keys(breadcrumbNameMap).forEach(item => {
if (pathToRegexp(item).test(url)) {
breadcrumb = breadcrumbNameMap[item];
}
});
}
return breadcrumb || {};
};
export default class BreadcrumbView extends PureComponent {
state = {
breadcrumb: null,
};
componentDidMount() {
this.getBreadcrumbDom();
}
componentDidUpdate(preProps) {
const { location } = this.props;
if (!location || !preProps.location) {
return;
}
const prePathname = preProps.location.pathname;
if (prePathname !== location.pathname) {
this.getBreadcrumbDom();
}
}
getBreadcrumbDom = () => {
const breadcrumb = this.conversionBreadcrumbList();
this.setState({
breadcrumb,
});
};
getBreadcrumbProps = () => {
const { routes, params, location, breadcrumbNameMap } = this.props;
return {
routes,
params,
routerLocation: location,
breadcrumbNameMap,
};
};
// Generated according to props
conversionFromProps = () => {
const { breadcrumbList, breadcrumbSeparator, itemRender, linkElement = 'a' } = this.props;
return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
{breadcrumbList.map(item => {
const title = itemRender ? itemRender(item) : item.title;
return (
<Breadcrumb.Item key={item.title}>
{item.href
? createElement(
linkElement,
{
[linkElement === 'a' ? 'href' : 'to']: item.href,
},
title
)
: title}
</Breadcrumb.Item>
);
})}
</Breadcrumb>
);
};
conversionFromLocation = (routerLocation, breadcrumbNameMap) => {
const { breadcrumbSeparator, home, itemRender, linkElement = 'a' } = this.props;
// Convert the url to an array
const pathSnippets = urlToList(routerLocation.pathname);
// Loop data mosaic routing
const extraBreadcrumbItems = pathSnippets.map((url, index) => {
const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
if (currentBreadcrumb.inherited) {
return null;
}
const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component;
const name = itemRender ? itemRender(currentBreadcrumb) : currentBreadcrumb.name;
return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? (
<Breadcrumb.Item key={url}>
{createElement(
isLinkable ? linkElement : 'span',
{ [linkElement === 'a' ? 'href' : 'to']: url },
name
)}
</Breadcrumb.Item>
) : null;
});
// Add home breadcrumbs to your head
extraBreadcrumbItems.unshift(
<Breadcrumb.Item key="home">
{createElement(
linkElement,
{
[linkElement === 'a' ? 'href' : 'to']: '/',
},
home || 'Home'
)}
</Breadcrumb.Item>
);
return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
{extraBreadcrumbItems}
</Breadcrumb>
);
};
/**
* 将参数转化为面包屑
* Convert parameters into breadcrumbs
*/
conversionBreadcrumbList = () => {
const { breadcrumbList, breadcrumbSeparator } = this.props;
const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps();
if (breadcrumbList && breadcrumbList.length) {
return this.conversionFromProps();
}
// 如果传入 routes 和 params 属性
// If pass routes and params attributes
if (routes && params) {
return (
<Breadcrumb
className={styles.breadcrumb}
routes={routes.filter(route => route.breadcrumbName)}
params={params}
itemRender={this.itemRender}
separator={breadcrumbSeparator}
/>
);
}
// 根据 location 生成 面包屑
// Generate breadcrumbs based on location
if (routerLocation && routerLocation.pathname) {
return this.conversionFromLocation(routerLocation, breadcrumbNameMap);
}
return null;
};
// 渲染Breadcrumb 子节点
// Render the Breadcrumb child node
itemRender = (route, params, routes, paths) => {
const { linkElement = 'a' } = this.props;
const last = routes.indexOf(route) === routes.length - 1;
return last || !route.component ? (
<span>{route.breadcrumbName}</span>
) : (
createElement(
linkElement,
{
href: paths.join('/') || '/',
to: paths.join('/') || '/',
},
route.breadcrumbName
)
);
};
render() {
const { breadcrumb } = this.state;
return breadcrumb;
}
}
...@@ -17,6 +17,7 @@ export interface IPageHeaderProps { ...@@ -17,6 +17,7 @@ export interface IPageHeaderProps {
style?: React.CSSProperties; style?: React.CSSProperties;
home?: React.ReactNode; home?: React.ReactNode;
wide?: boolean; wide?: boolean;
hiddenBreadcrumb?:boolean;
} }
export default class PageHeader extends React.Component<IPageHeaderProps, any> {} export default class PageHeader extends React.Component<IPageHeaderProps, any> {}
import React, { PureComponent, createElement } from 'react'; import React, { PureComponent } from 'react';
import pathToRegexp from 'path-to-regexp'; import { Tabs, Skeleton } from 'antd';
import { Breadcrumb, Tabs, Skeleton } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
import { urlToList } from '../_utils/pathTools'; import BreadcrumbView from './breadcrumb';
const { TabPane } = Tabs; const { TabPane } = Tabs;
export const getBreadcrumb = (breadcrumbNameMap, url) => {
let breadcrumb = breadcrumbNameMap[url];
if (!breadcrumb) {
Object.keys(breadcrumbNameMap).forEach(item => {
if (pathToRegexp(item).test(url)) {
breadcrumb = breadcrumbNameMap[item];
}
});
}
return breadcrumb || {};
};
export default class PageHeader extends PureComponent { export default class PageHeader extends PureComponent {
state = {
breadcrumb: null,
};
componentDidMount() {
this.getBreadcrumbDom();
}
componentDidUpdate(preProps) {
const { location } = this.props;
if (!location || !preProps.location) {
return;
}
const prePathname = preProps.location.pathname;
if (prePathname !== location.pathname) {
this.getBreadcrumbDom();
}
}
onChange = key => { onChange = key => {
const { onTabChange } = this.props; const { onTabChange } = this.props;
if (onTabChange) { if (onTabChange) {
...@@ -45,139 +13,6 @@ export default class PageHeader extends PureComponent { ...@@ -45,139 +13,6 @@ export default class PageHeader extends PureComponent {
} }
}; };
getBreadcrumbProps = () => {
const { routes, params, location, breadcrumbNameMap } = this.props;
return {
routes,
params,
routerLocation: location,
breadcrumbNameMap,
};
};
getBreadcrumbDom = () => {
const breadcrumb = this.conversionBreadcrumbList();
this.setState({
breadcrumb,
});
};
// Generated according to props
conversionFromProps = () => {
const { breadcrumbList, breadcrumbSeparator, itemRender, linkElement = 'a' } = this.props;
return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
{breadcrumbList.map(item => {
const title = itemRender ? itemRender(item) : item.title;
return (
<Breadcrumb.Item key={item.title}>
{item.href
? createElement(
linkElement,
{
[linkElement === 'a' ? 'href' : 'to']: item.href,
},
title
)
: title}
</Breadcrumb.Item>
);
})}
</Breadcrumb>
);
};
conversionFromLocation = (routerLocation, breadcrumbNameMap) => {
const { breadcrumbSeparator, home, itemRender, linkElement = 'a' } = this.props;
// Convert the url to an array
const pathSnippets = urlToList(routerLocation.pathname);
// Loop data mosaic routing
const extraBreadcrumbItems = pathSnippets.map((url, index) => {
const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
if (currentBreadcrumb.inherited) {
return null;
}
const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component;
const name = itemRender ? itemRender(currentBreadcrumb) : currentBreadcrumb.name;
return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? (
<Breadcrumb.Item key={url}>
{createElement(
isLinkable ? linkElement : 'span',
{ [linkElement === 'a' ? 'href' : 'to']: url },
name
)}
</Breadcrumb.Item>
) : null;
});
// Add home breadcrumbs to your head
extraBreadcrumbItems.unshift(
<Breadcrumb.Item key="home">
{createElement(
linkElement,
{
[linkElement === 'a' ? 'href' : 'to']: '/',
},
home || 'Home'
)}
</Breadcrumb.Item>
);
return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
{extraBreadcrumbItems}
</Breadcrumb>
);
};
/**
* 将参数转化为面包屑
* Convert parameters into breadcrumbs
*/
conversionBreadcrumbList = () => {
const { breadcrumbList, breadcrumbSeparator } = this.props;
const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps();
if (breadcrumbList && breadcrumbList.length) {
return this.conversionFromProps();
}
// 如果传入 routes 和 params 属性
// If pass routes and params attributes
if (routes && params) {
return (
<Breadcrumb
className={styles.breadcrumb}
routes={routes.filter(route => route.breadcrumbName)}
params={params}
itemRender={this.itemRender}
separator={breadcrumbSeparator}
/>
);
}
// 根据 location 生成 面包屑
// Generate breadcrumbs based on location
if (routerLocation && routerLocation.pathname) {
return this.conversionFromLocation(routerLocation, breadcrumbNameMap);
}
return null;
};
// 渲染Breadcrumb 子节点
// Render the Breadcrumb child node
itemRender = (route, params, routes, paths) => {
const { linkElement = 'a' } = this.props;
const last = routes.indexOf(route) === routes.length - 1;
return last || !route.component ? (
<span>{route.breadcrumbName}</span>
) : (
createElement(
linkElement,
{
href: paths.join('/') || '/',
to: paths.join('/') || '/',
},
route.breadcrumbName
)
);
};
render() { render() {
const { const {
title, title,
...@@ -192,8 +27,8 @@ export default class PageHeader extends PureComponent { ...@@ -192,8 +27,8 @@ export default class PageHeader extends PureComponent {
tabBarExtraContent, tabBarExtraContent,
loading = false, loading = false,
wide = false, wide = false,
hiddenBreadcrumb = false,
} = this.props; } = this.props;
const { breadcrumb } = this.state;
const clsString = classNames(styles.pageHeader, className); const clsString = classNames(styles.pageHeader, className);
const activeKeyProps = {}; const activeKeyProps = {};
...@@ -213,7 +48,7 @@ export default class PageHeader extends PureComponent { ...@@ -213,7 +48,7 @@ export default class PageHeader extends PureComponent {
paragraph={{ rows: 3 }} paragraph={{ rows: 3 }}
avatar={{ size: 'large', shape: 'circle' }} avatar={{ size: 'large', shape: 'circle' }}
> >
{breadcrumb} {hiddenBreadcrumb ? null : <BreadcrumbView {...this.props} />}
<div className={styles.detail}> <div className={styles.detail}>
{logo && <div className={styles.logo}>{logo}</div>} {logo && <div className={styles.logo}>{logo}</div>}
<div className={styles.main}> <div className={styles.main}>
......
...@@ -20,6 +20,7 @@ order: 11 ...@@ -20,6 +20,7 @@ order: 11
| content | 内容区 | ReactNode | - | | content | 内容区 | ReactNode | - |
| extraContent | 额外内容区,位于content的右侧 | ReactNode | - | | extraContent | 额外内容区,位于content的右侧 | ReactNode | - |
| breadcrumbList | 面包屑数据,配置了此属性时 `routes` `params` `location` `breadcrumbNameMap` 无效 | array<{title: ReactNode, href?: string}> | - | | breadcrumbList | 面包屑数据,配置了此属性时 `routes` `params` `location` `breadcrumbNameMap` 无效 | array<{title: ReactNode, href?: string}> | - |
| hiddenBreadcrumb |隐藏面包屑 | boolean | false |
| routes | 面包屑相关属性,router 的路由栈信息 | object[] | - | | routes | 面包屑相关属性,router 的路由栈信息 | object[] | - |
| params | 面包屑相关属性,路由的参数 | object | - | | params | 面包屑相关属性,路由的参数 | object | - |
| location | 面包屑相关属性,当前的路由信息 | object | - | | location | 面包屑相关属性,当前的路由信息 | object | - |
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment