breadcrumb.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import React from 'react';
  2. import pathToRegexp from 'path-to-regexp';
  3. import Link from 'umi/link';
  4. import { formatMessage } from 'umi-plugin-react/locale';
  5. import { urlToList } from '../_utils/pathTools';
  6. import { menu } from '../../defaultSettings';
  7. // 渲染Breadcrumb 子节点
  8. // Render the Breadcrumb child node
  9. const itemRender = (route, params, routes, paths) => {
  10. const last = routes.indexOf(route) === routes.length - 1;
  11. // if path is home, use Link。
  12. if (route.path === '/') {
  13. return <Link to={paths.join('/')}>{route.breadcrumbName}</Link>;
  14. }
  15. return last || !route.component ? (
  16. <span>{route.breadcrumbName}</span>
  17. ) : (
  18. <Link to={paths.join('/')}>{route.breadcrumbName}</Link>
  19. );
  20. };
  21. const renderItemLocal = item => {
  22. if (item.locale) {
  23. const name = menu.disableLocal
  24. ? item.name
  25. : formatMessage({ id: item.locale, defaultMessage: item.name });
  26. return name;
  27. }
  28. return item.name;
  29. };
  30. export const getBreadcrumb = (breadcrumbNameMap, url) => {
  31. let breadcrumb = breadcrumbNameMap[url];
  32. if (!breadcrumb) {
  33. Object.keys(breadcrumbNameMap).forEach(item => {
  34. if (pathToRegexp(item).test(url)) {
  35. breadcrumb = breadcrumbNameMap[item];
  36. }
  37. });
  38. }
  39. return breadcrumb || {};
  40. };
  41. export const getBreadcrumbProps = props => {
  42. const { routes, params, location, breadcrumbNameMap } = props;
  43. return {
  44. routes,
  45. params,
  46. routerLocation: location,
  47. breadcrumbNameMap,
  48. };
  49. };
  50. // Generated according to props
  51. const conversionFromProps = props => {
  52. const { breadcrumbList } = props;
  53. return breadcrumbList.map(item => {
  54. const { title, href } = item;
  55. return {
  56. path: href,
  57. breadcrumbName: title,
  58. };
  59. });
  60. };
  61. const conversionFromLocation = (routerLocation, breadcrumbNameMap, props) => {
  62. const { home } = props;
  63. // Convert the url to an array
  64. const pathSnippets = urlToList(routerLocation.pathname);
  65. // Loop data mosaic routing
  66. const extraBreadcrumbItems = pathSnippets
  67. .map(url => {
  68. const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
  69. if (currentBreadcrumb.inherited) {
  70. return null;
  71. }
  72. const name = renderItemLocal(currentBreadcrumb);
  73. const { hideInBreadcrumb } = currentBreadcrumb;
  74. return name && !hideInBreadcrumb
  75. ? {
  76. path: url,
  77. breadcrumbName: name,
  78. }
  79. : null;
  80. })
  81. .filter(item => item !== null);
  82. // Add home breadcrumbs to your head if defined
  83. if (home) {
  84. extraBreadcrumbItems.unshift({
  85. path: '/',
  86. breadcrumbName: home,
  87. });
  88. }
  89. return extraBreadcrumbItems;
  90. };
  91. /**
  92. * 将参数转化为面包屑
  93. * Convert parameters into breadcrumbs
  94. */
  95. export const conversionBreadcrumbList = props => {
  96. const { breadcrumbList } = props;
  97. const { routes, params, routerLocation, breadcrumbNameMap } = getBreadcrumbProps(props);
  98. if (breadcrumbList && breadcrumbList.length) {
  99. return {
  100. routes: conversionFromProps(props),
  101. params,
  102. itemRender,
  103. };
  104. }
  105. // 如果传入 routes 和 params 属性
  106. // If pass routes and params attributes
  107. if (routes && params) {
  108. return {
  109. routes: routes.filter(route => route.breadcrumbName),
  110. params,
  111. itemRender,
  112. };
  113. }
  114. // 根据 location 生成 面包屑
  115. // Generate breadcrumbs based on location
  116. if (routerLocation && routerLocation.pathname) {
  117. return {
  118. routes: conversionFromLocation(routerLocation, breadcrumbNameMap, props),
  119. itemRender,
  120. };
  121. }
  122. return {};
  123. };