|
|
@ -4,7 +4,7 @@ import pathToRegexp from 'path-to-regexp'; |
|
|
import { Breadcrumb, Tabs } from 'antd'; |
|
|
import { Breadcrumb, Tabs } 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'; |
|
|
|
|
|
|
|
|
const { TabPane } = Tabs; |
|
|
const { TabPane } = Tabs; |
|
|
export function getBreadcrumb(breadcrumbNameMap, url) { |
|
|
export function getBreadcrumb(breadcrumbNameMap, url) { |
|
|
@ -19,14 +19,6 @@ export function getBreadcrumb(breadcrumbNameMap, url) { |
|
|
return breadcrumb || {}; |
|
|
return breadcrumb || {}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
|
|
|
|
|
|
export function urlToList(url) { |
|
|
|
|
|
const urllist = url.split('/').filter(i => i); |
|
|
|
|
|
return urllist.map((urlItem, index) => { |
|
|
|
|
|
return `/${urllist.slice(0, index + 1).join('/')}`; |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export default class PageHeader extends PureComponent { |
|
|
export default class PageHeader extends PureComponent { |
|
|
static contextTypes = { |
|
|
static contextTypes = { |
|
|
routes: PropTypes.array, |
|
|
routes: PropTypes.array, |
|
|
@ -44,29 +36,35 @@ export default class PageHeader extends PureComponent { |
|
|
routes: this.props.routes || this.context.routes, |
|
|
routes: this.props.routes || this.context.routes, |
|
|
params: this.props.params || this.context.params, |
|
|
params: this.props.params || this.context.params, |
|
|
routerLocation: this.props.location || this.context.location, |
|
|
routerLocation: this.props.location || this.context.location, |
|
|
breadcrumbNameMap: this.props.breadcrumbNameMap || this.context.breadcrumbNameMap, |
|
|
breadcrumbNameMap: |
|
|
|
|
|
this.props.breadcrumbNameMap || this.context.breadcrumbNameMap, |
|
|
}; |
|
|
}; |
|
|
}; |
|
|
}; |
|
|
// Generated according to props
|
|
|
// Generated according to props
|
|
|
conversionFromProps= () => { |
|
|
conversionFromProps = () => { |
|
|
const { |
|
|
const { |
|
|
breadcrumbList, breadcrumbSeparator, linkElement = 'a', |
|
|
breadcrumbList, |
|
|
|
|
|
breadcrumbSeparator, |
|
|
|
|
|
linkElement = 'a', |
|
|
} = this.props; |
|
|
} = this.props; |
|
|
return ( |
|
|
return ( |
|
|
<Breadcrumb |
|
|
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}> |
|
|
className={styles.breadcrumb} |
|
|
|
|
|
separator={breadcrumbSeparator} |
|
|
|
|
|
> |
|
|
|
|
|
{breadcrumbList.map(item => ( |
|
|
{breadcrumbList.map(item => ( |
|
|
<Breadcrumb.Item key={item.title}> |
|
|
<Breadcrumb.Item key={item.title}> |
|
|
{item.href ? (createElement(linkElement, { |
|
|
{item.href |
|
|
[linkElement === 'a' ? 'href' : 'to']: item.href, |
|
|
? createElement( |
|
|
}, item.title)) : item.title} |
|
|
linkElement, |
|
|
|
|
|
{ |
|
|
|
|
|
[linkElement === 'a' ? 'href' : 'to']: item.href, |
|
|
|
|
|
}, |
|
|
|
|
|
item.title, |
|
|
|
|
|
) |
|
|
|
|
|
: item.title} |
|
|
</Breadcrumb.Item> |
|
|
</Breadcrumb.Item> |
|
|
))} |
|
|
))} |
|
|
</Breadcrumb> |
|
|
</Breadcrumb> |
|
|
); |
|
|
); |
|
|
} |
|
|
}; |
|
|
conversionFromLocation = (routerLocation, breadcrumbNameMap) => { |
|
|
conversionFromLocation = (routerLocation, breadcrumbNameMap) => { |
|
|
const { breadcrumbSeparator, linkElement = 'a' } = this.props; |
|
|
const { breadcrumbSeparator, linkElement = 'a' } = this.props; |
|
|
// Convert the url to an array
|
|
|
// Convert the url to an array
|
|
|
@ -74,7 +72,8 @@ export default class PageHeader extends PureComponent { |
|
|
// Loop data mosaic routing
|
|
|
// Loop data mosaic routing
|
|
|
const extraBreadcrumbItems = pathSnippets.map((url, index) => { |
|
|
const extraBreadcrumbItems = pathSnippets.map((url, index) => { |
|
|
const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); |
|
|
const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); |
|
|
const isLinkable = (index !== pathSnippets.length - 1) && currentBreadcrumb.component; |
|
|
const isLinkable = |
|
|
|
|
|
index !== pathSnippets.length - 1 && currentBreadcrumb.component; |
|
|
return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? ( |
|
|
return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? ( |
|
|
<Breadcrumb.Item key={url}> |
|
|
<Breadcrumb.Item key={url}> |
|
|
{createElement( |
|
|
{createElement( |
|
|
@ -88,26 +87,33 @@ export default class PageHeader extends PureComponent { |
|
|
// Add home breadcrumbs to your head
|
|
|
// Add home breadcrumbs to your head
|
|
|
extraBreadcrumbItems.unshift( |
|
|
extraBreadcrumbItems.unshift( |
|
|
<Breadcrumb.Item key="home"> |
|
|
<Breadcrumb.Item key="home"> |
|
|
{createElement(linkElement, { |
|
|
{createElement( |
|
|
[linkElement === 'a' ? 'href' : 'to']: '/' }, '首页')} |
|
|
linkElement, |
|
|
</Breadcrumb.Item> |
|
|
{ |
|
|
|
|
|
[linkElement === 'a' ? 'href' : 'to']: '/', |
|
|
|
|
|
}, |
|
|
|
|
|
'首页', |
|
|
|
|
|
)} |
|
|
|
|
|
</Breadcrumb.Item>, |
|
|
); |
|
|
); |
|
|
return ( |
|
|
return ( |
|
|
<Breadcrumb |
|
|
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}> |
|
|
className={styles.breadcrumb} |
|
|
|
|
|
separator={breadcrumbSeparator} |
|
|
|
|
|
> |
|
|
|
|
|
{extraBreadcrumbItems} |
|
|
{extraBreadcrumbItems} |
|
|
</Breadcrumb> |
|
|
</Breadcrumb> |
|
|
); |
|
|
); |
|
|
} |
|
|
}; |
|
|
/** |
|
|
/** |
|
|
* 将参数转化为面包屑 |
|
|
* 将参数转化为面包屑 |
|
|
* Convert parameters into breadcrumbs |
|
|
* Convert parameters into breadcrumbs |
|
|
*/ |
|
|
*/ |
|
|
conversionBreadcrumbList = () => { |
|
|
conversionBreadcrumbList = () => { |
|
|
const { breadcrumbList, breadcrumbSeparator } = this.props; |
|
|
const { breadcrumbList, breadcrumbSeparator } = this.props; |
|
|
const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps(); |
|
|
const { |
|
|
|
|
|
routes, |
|
|
|
|
|
params, |
|
|
|
|
|
routerLocation, |
|
|
|
|
|
breadcrumbNameMap, |
|
|
|
|
|
} = this.getBreadcrumbProps(); |
|
|
if (breadcrumbList && breadcrumbList.length) { |
|
|
if (breadcrumbList && breadcrumbList.length) { |
|
|
return this.conversionFromProps(); |
|
|
return this.conversionFromProps(); |
|
|
} |
|
|
} |
|
|
@ -126,28 +132,41 @@ export default class PageHeader extends PureComponent { |
|
|
} |
|
|
} |
|
|
// 根据 location 生成 面包屑
|
|
|
// 根据 location 生成 面包屑
|
|
|
// Generate breadcrumbs based on location
|
|
|
// Generate breadcrumbs based on location
|
|
|
if (location && location.pathname) { |
|
|
if (routerLocation && routerLocation.pathname) { |
|
|
return this.conversionFromLocation(routerLocation, breadcrumbNameMap); |
|
|
return this.conversionFromLocation(routerLocation, breadcrumbNameMap); |
|
|
} |
|
|
} |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
}; |
|
|
// 渲染Breadcrumb 子节点
|
|
|
// 渲染Breadcrumb 子节点
|
|
|
// Render the Breadcrumb child node
|
|
|
// Render the Breadcrumb child node
|
|
|
itemRender = (route, params, routes, paths) => { |
|
|
itemRender = (route, params, routes, paths) => { |
|
|
const { linkElement = 'a' } = this.props; |
|
|
const { linkElement = 'a' } = this.props; |
|
|
const last = routes.indexOf(route) === routes.length - 1; |
|
|
const last = routes.indexOf(route) === routes.length - 1; |
|
|
return (last || !route.component) |
|
|
return last || !route.component ? ( |
|
|
? <span>{route.breadcrumbName}</span> |
|
|
<span>{route.breadcrumbName}</span> |
|
|
: createElement(linkElement, { |
|
|
) : ( |
|
|
href: paths.join('/') || '/', |
|
|
createElement( |
|
|
to: paths.join('/') || '/', |
|
|
linkElement, |
|
|
}, route.breadcrumbName); |
|
|
{ |
|
|
} |
|
|
href: paths.join('/') || '/', |
|
|
|
|
|
to: paths.join('/') || '/', |
|
|
|
|
|
}, |
|
|
|
|
|
route.breadcrumbName, |
|
|
|
|
|
) |
|
|
|
|
|
); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
render() { |
|
|
render() { |
|
|
const { |
|
|
const { |
|
|
title, logo, action, content, extraContent, |
|
|
title, |
|
|
tabList, className, tabActiveKey, tabBarExtraContent, |
|
|
logo, |
|
|
|
|
|
action, |
|
|
|
|
|
content, |
|
|
|
|
|
extraContent, |
|
|
|
|
|
tabList, |
|
|
|
|
|
className, |
|
|
|
|
|
tabActiveKey, |
|
|
|
|
|
tabBarExtraContent, |
|
|
} = this.props; |
|
|
} = this.props; |
|
|
const clsString = classNames(styles.pageHeader, className); |
|
|
const clsString = classNames(styles.pageHeader, className); |
|
|
|
|
|
|
|
|
@ -175,12 +194,13 @@ export default class PageHeader extends PureComponent { |
|
|
</div> |
|
|
</div> |
|
|
<div className={styles.row}> |
|
|
<div className={styles.row}> |
|
|
{content && <div className={styles.content}>{content}</div>} |
|
|
{content && <div className={styles.content}>{content}</div>} |
|
|
{extraContent && <div className={styles.extraContent}>{extraContent}</div>} |
|
|
{extraContent && ( |
|
|
|
|
|
<div className={styles.extraContent}>{extraContent}</div> |
|
|
|
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
{ |
|
|
{tabList && |
|
|
tabList && |
|
|
|
|
|
tabList.length && ( |
|
|
tabList.length && ( |
|
|
<Tabs |
|
|
<Tabs |
|
|
className={styles.tabs} |
|
|
className={styles.tabs} |
|
|
@ -188,12 +208,9 @@ export default class PageHeader extends PureComponent { |
|
|
onChange={this.onChange} |
|
|
onChange={this.onChange} |
|
|
tabBarExtraContent={tabBarExtraContent} |
|
|
tabBarExtraContent={tabBarExtraContent} |
|
|
> |
|
|
> |
|
|
{ |
|
|
{tabList.map(item => <TabPane tab={item.tab} key={item.key} />)} |
|
|
tabList.map(item => <TabPane tab={item.tab} key={item.key} />) |
|
|
|
|
|
} |
|
|
|
|
|
</Tabs> |
|
|
</Tabs> |
|
|
) |
|
|
)} |
|
|
} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|