@tntd/bread-crumb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.octopus/ar-EG/index.js +5 -0
- package/.octopus/ar-EG/src.js +5 -0
- package/.octopus/en-US/index.js +5 -0
- package/.octopus/en-US/src.js +5 -0
- package/.octopus/es-ES/index.js +5 -0
- package/.octopus/es-ES/src.js +5 -0
- package/.octopus/ko-KR/index.js +5 -0
- package/.octopus/ko-KR/src.js +5 -0
- package/.octopus/th-TH/index.js +5 -0
- package/.octopus/th-TH/src.js +5 -0
- package/.octopus/zh-CN/index.js +5 -0
- package/.octopus/zh-CN/src.js +5 -0
- package/.octopus/zh-TW/index.js +5 -0
- package/.octopus/zh-TW/src.js +5 -0
- package/es/I18N.js +33 -0
- package/es/bread-crumb.md +93 -0
- package/es/index.js +336 -0
- package/es/index.less +28 -0
- package/es/locale/ar_EG.js +11 -0
- package/es/locale/en_US.js +11 -0
- package/es/locale/es_ES.js +11 -0
- package/es/locale/ko_KR.js +11 -0
- package/es/locale/th_TH.js +11 -0
- package/es/locale/zh_CN.js +11 -0
- package/es/locale/zh_TW.js +11 -0
- package/package.json +22 -0
- package/readme.md +84 -0
- package/src/I18N.js +27 -0
- package/src/bread-crumb.md +93 -0
- package/src/index.js +331 -0
- package/src/index.less +28 -0
- package/src/locale/ar_EG.js +5 -0
- package/src/locale/en_US.js +5 -0
- package/src/locale/es_ES.js +5 -0
- package/src/locale/ko_KR.js +5 -0
- package/src/locale/th_TH.js +5 -0
- package/src/locale/zh_CN.js +5 -0
- package/src/locale/zh_TW.js +5 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _index = _interopRequireDefault(require("../../.octopus/zh-TW/index.js"));
|
|
9
|
+
var _default = exports["default"] = {
|
|
10
|
+
TntdBreadCrumb: _index["default"]
|
|
11
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tntd/bread-crumb",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "react4.0的面包屑",
|
|
5
|
+
"author": "zefei.zhou <zefei.zhou@tongdun.net>",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rm -rf ./es && npx babel src --out-dir es --copy-files"
|
|
9
|
+
},
|
|
10
|
+
"main": "es/index.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"es",
|
|
13
|
+
"src",
|
|
14
|
+
".octopus"
|
|
15
|
+
],
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"antd": "^3.0.0",
|
|
18
|
+
"tntd": ">=3.1.0",
|
|
19
|
+
"react": ">=16.8.0",
|
|
20
|
+
"dva": ">=2.4.1"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
### 安装和初始化
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
npm install @tddc/bread-crumb --save
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
### 面包屑
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
import React, { memo } from 'react';
|
|
11
|
+
import { createBrowserHistory } from 'history';
|
|
12
|
+
import { Router, Route, Switch } from 'react-router-dom';
|
|
13
|
+
import BreadCrumb from '@tddc/bread-crumb';
|
|
14
|
+
import Detail from '../Test/Detail';
|
|
15
|
+
import List from '../Test/List';
|
|
16
|
+
|
|
17
|
+
const BreadCrumbDefault = BreadCrumb(
|
|
18
|
+
(props) => {
|
|
19
|
+
return (
|
|
20
|
+
<Switch>
|
|
21
|
+
<Route name="面包屑" path={`/components/bread-crumb`} exact component={Detail} />
|
|
22
|
+
<Route
|
|
23
|
+
name="组件总览"
|
|
24
|
+
component={List}
|
|
25
|
+
path="/components"
|
|
26
|
+
query={[{ token: 'parentToken' }]}
|
|
27
|
+
/>
|
|
28
|
+
</Switch>
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
// BreadCrumbCustom:(breadList)=>{
|
|
33
|
+
// console.log(breadList)
|
|
34
|
+
// return <div>{breadList?.map(v=>v?.name)}</div>
|
|
35
|
+
// },
|
|
36
|
+
// BreadCrumbPrototype:{
|
|
37
|
+
// separator:"->",
|
|
38
|
+
// className:"z-c-breadcrumb"
|
|
39
|
+
// }
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export default memo(BreadCrumbDefault);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### 🚀 高阶组件
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
BreadCrumb(
|
|
50
|
+
(props) => {
|
|
51
|
+
return (
|
|
52
|
+
<Switch>
|
|
53
|
+
<Route name="面包屑" path={`/components/bread-crumb`} exact component={Detail} />
|
|
54
|
+
<Route name="组件总览" component={List} path="/components" />
|
|
55
|
+
</Switch>
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
breadCrumbCustomName: ({ breadList, path }) => {
|
|
60
|
+
return 'aa';
|
|
61
|
+
},
|
|
62
|
+
// BreadCrumbCustom:(breadList)=>{
|
|
63
|
+
// console.log(breadList)
|
|
64
|
+
// return <div>{breadList?.map(v=>v?.name)}</div>
|
|
65
|
+
// },
|
|
66
|
+
// BreadCrumbPrototype:{
|
|
67
|
+
// separator:"->",
|
|
68
|
+
// className:"z-c-breadcrumb"
|
|
69
|
+
// }
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
75
|
+
| ------------------- | ------------------------------------------ | --------------- | ------ |
|
|
76
|
+
| component | 子路由定义,可嵌套 | | |
|
|
77
|
+
| BreadCrumbCustom | 自定义面包屑 | (breadList)=>{} | null |
|
|
78
|
+
| BreadCrumbPrototype | 面包屑属性,同 antd 的 BreadCrumb 组件参数 | Object | {} |
|
|
79
|
+
| useCache | 开启缓存模式,记录页面跳转地址 | false | {} |
|
|
80
|
+
|
|
81
|
+
| Route 参数 | 说明 | 类型 | 默认值 |
|
|
82
|
+
| -------------- | ---------------------- | --------------------------- | ------ |
|
|
83
|
+
| query | 需要往下传递的参数 | | |
|
|
84
|
+
| routerItemHide | 当前页不需要展示面包屑 | (location)=>{} 或者 Boolean | false |
|
package/src/I18N.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Cookies from 'universal-cookie';
|
|
2
|
+
import zhCN from '../.octopus/zh-CN';
|
|
3
|
+
import zhTW from '../.octopus/zh-TW';
|
|
4
|
+
import enUS from '../.octopus/en-US';
|
|
5
|
+
import thTH from '../.octopus/th-TH';
|
|
6
|
+
import arEG from '../.octopus/ar-EG';
|
|
7
|
+
import koKR from '../.octopus/ko-KR';
|
|
8
|
+
import esES from '../.octopus/es-ES';
|
|
9
|
+
|
|
10
|
+
const cookies = new Cookies();
|
|
11
|
+
|
|
12
|
+
const mapLocale = {
|
|
13
|
+
'zh-cn': zhCN,
|
|
14
|
+
'zh-tw': zhTW,
|
|
15
|
+
en: enUS,
|
|
16
|
+
th: thTH, // 泰语
|
|
17
|
+
ar: arEG, // 阿拉伯语(埃及)
|
|
18
|
+
ko: koKR, // 韩语
|
|
19
|
+
es: esES // 西班牙语
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getLang = () => {
|
|
23
|
+
const lang = cookies.get('lang');
|
|
24
|
+
return lang !== 'cn' ? lang : 'zh-cn';
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default mapLocale;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: react-router4.0的面包屑
|
|
3
|
+
group:
|
|
4
|
+
path: /
|
|
5
|
+
nav:
|
|
6
|
+
title: 组件
|
|
7
|
+
path: /components
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
### 安装和初始化
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
npm install @tddc/bread-crumb --save
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### 面包屑
|
|
17
|
+
|
|
18
|
+
```jsx
|
|
19
|
+
import React, { memo } from 'react';
|
|
20
|
+
import { createBrowserHistory } from 'history';
|
|
21
|
+
import { Router, Route, Switch } from 'react-router-dom';
|
|
22
|
+
import BreadCrumb from '@tddc/bread-crumb';
|
|
23
|
+
import Detail from '../Test/Detail';
|
|
24
|
+
import List from '../Test/List';
|
|
25
|
+
|
|
26
|
+
const BreadCrumbDefault = BreadCrumb(
|
|
27
|
+
(props) => {
|
|
28
|
+
return (
|
|
29
|
+
<Switch>
|
|
30
|
+
<Route name="面包屑" path={`/components/bread-crumb`} exact component={Detail} />
|
|
31
|
+
<Route
|
|
32
|
+
name="组件总览"
|
|
33
|
+
component={List}
|
|
34
|
+
path="/components"
|
|
35
|
+
query={[{ token: 'parentToken' }]}
|
|
36
|
+
/>
|
|
37
|
+
</Switch>
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
// BreadCrumbCustom:(breadList)=>{
|
|
42
|
+
// console.log(breadList)
|
|
43
|
+
// return <div>{breadList?.map(v=>v?.name)}</div>
|
|
44
|
+
// },
|
|
45
|
+
// BreadCrumbPrototype:{
|
|
46
|
+
// separator:"->",
|
|
47
|
+
// className:"z-c-breadcrumb"
|
|
48
|
+
// }
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export default memo(BreadCrumbDefault);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 🚀 高阶组件
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
BreadCrumb(
|
|
59
|
+
(props) => {
|
|
60
|
+
return (
|
|
61
|
+
<Switch>
|
|
62
|
+
<Route name="面包屑" path={`/components/bread-crumb`} exact component={Detail} />
|
|
63
|
+
<Route name="组件总览" component={List} path="/components" />
|
|
64
|
+
</Switch>
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
breadCrumbCustomName: ({ breadList, path }) => {
|
|
69
|
+
return 'aa';
|
|
70
|
+
},
|
|
71
|
+
// BreadCrumbCustom:(breadList)=>{
|
|
72
|
+
// console.log(breadList)
|
|
73
|
+
// return <div>{breadList?.map(v=>v?.name)}</div>
|
|
74
|
+
// },
|
|
75
|
+
// BreadCrumbPrototype:{
|
|
76
|
+
// separator:"->",
|
|
77
|
+
// className:"z-c-breadcrumb"
|
|
78
|
+
// }
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
84
|
+
| ------------------- | ------------------------------------------ | --------------- | ------ |
|
|
85
|
+
| component | 子路由定义,可嵌套 | | |
|
|
86
|
+
| BreadCrumbCustom | 自定义面包屑 | (breadList)=>{} | null |
|
|
87
|
+
| BreadCrumbPrototype | 面包屑属性,同 antd 的 BreadCrumb 组件参数 | Object | {} |
|
|
88
|
+
| useCache | 开启缓存模式,记录页面跳转地址 | false | {} |
|
|
89
|
+
|
|
90
|
+
| Route 参数 | 说明 | 类型 | 默认值 |
|
|
91
|
+
| -------------- | ---------------------- | --------------------------- | ------ |
|
|
92
|
+
| query | 需要往下传递的参数 | | |
|
|
93
|
+
| routerItemHide | 当前页不需要展示面包屑 | (location)=>{} 或者 Boolean | false |
|
package/src/index.js
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import mapLocale, { getLang } from './I18N';
|
|
2
|
+
import { useEffect, useState, useMemo, useRef } from 'react';
|
|
3
|
+
import { Breadcrumb, Icon } from 'tntd';
|
|
4
|
+
import LocaleReceiver from 'antd/es/locale-provider/LocaleReceiver'
|
|
5
|
+
import { withRouter, matchPath, Link } from 'dva/router';
|
|
6
|
+
import './index.less';
|
|
7
|
+
const searchToObject = (search) => {
|
|
8
|
+
let pairs = search.substring(1).split('&');
|
|
9
|
+
let obj = {};
|
|
10
|
+
let pair;
|
|
11
|
+
let i;
|
|
12
|
+
for (i in pairs) {
|
|
13
|
+
if (pairs[i] === '') {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
pair = pairs[i].split('=');
|
|
18
|
+
// obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
|
|
19
|
+
obj[decodeURIComponent(pair[0])] = pair[1];
|
|
20
|
+
}
|
|
21
|
+
return obj;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getParams = (params) => {
|
|
25
|
+
let paramStr = '';
|
|
26
|
+
Object.keys(params).forEach((item) => {
|
|
27
|
+
const tempParamStr = encodeURIComponent(params[item]);
|
|
28
|
+
if (paramStr === '') {
|
|
29
|
+
paramStr = `${item}=${tempParamStr}`;
|
|
30
|
+
} else {
|
|
31
|
+
paramStr = `${paramStr}&${item}=${tempParamStr}`;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return paramStr;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const flatten = (arr) => {
|
|
38
|
+
let res = [];
|
|
39
|
+
const curArr = arr?.props?.children;
|
|
40
|
+
for (let i = 0, length = curArr?.length; i < length; i++) {
|
|
41
|
+
if (Array.isArray(curArr[i]?.props?.children)) {
|
|
42
|
+
res = res.concat(flatten(curArr[i]));
|
|
43
|
+
} else {
|
|
44
|
+
res.push(curArr[i]?.props);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return res;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default (WrapperComponent, rest) => {
|
|
51
|
+
const {
|
|
52
|
+
useMemory,
|
|
53
|
+
memoryHandle,
|
|
54
|
+
useCache, // 使用内部缓存
|
|
55
|
+
defaultSearch = ['currentTab', 'current'],
|
|
56
|
+
BreadCrumbCustom,
|
|
57
|
+
breadCrumbCustomName,
|
|
58
|
+
BreadCrumbPrototype = {},
|
|
59
|
+
showHeader,
|
|
60
|
+
forceNoHeader,
|
|
61
|
+
lang,
|
|
62
|
+
version,
|
|
63
|
+
locale,
|
|
64
|
+
} = rest || {};
|
|
65
|
+
let breadCacheList = [];
|
|
66
|
+
|
|
67
|
+
return withRouter((props) => {
|
|
68
|
+
const { match, location, separator } = props || {};
|
|
69
|
+
const { pathname, search } = location || {};
|
|
70
|
+
const children = WrapperComponent({ ...props });
|
|
71
|
+
const [breadList, setBreadList] = useState([]);
|
|
72
|
+
// 记录链接上需要保留的query参数
|
|
73
|
+
const searchObj = searchToObject(search);
|
|
74
|
+
const curVersion = version || localStorage.getItem('app_version') || 'v3';
|
|
75
|
+
|
|
76
|
+
const breadListRef = useRef();
|
|
77
|
+
breadListRef.current = useMemo(() => {
|
|
78
|
+
return breadList;
|
|
79
|
+
}, [breadList]);
|
|
80
|
+
|
|
81
|
+
const watchReplaceState = (e) => {
|
|
82
|
+
const newBread = (breadListRef.current || []).slice();
|
|
83
|
+
const url = e?.arguments?.[2];
|
|
84
|
+
if (newBread?.length && url) {
|
|
85
|
+
if (url !== newBread[newBread?.length - 1].url) {
|
|
86
|
+
newBread[newBread?.length - 1].url = url;
|
|
87
|
+
setBreadList(newBread);
|
|
88
|
+
breadCacheList = newBread;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (useCache) {
|
|
94
|
+
window.addEventListener('replaceState', watchReplaceState);
|
|
95
|
+
return () => {
|
|
96
|
+
window.removeEventListener('replaceState', watchReplaceState);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}, [breadList, useCache]);
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (useCache && useMemory && breadList?.length > 0) {
|
|
103
|
+
const localStorageKey = breadList?.[0]?.path;
|
|
104
|
+
if (breadList?.length > 1) {
|
|
105
|
+
if (breadList?.[0]?.path) {
|
|
106
|
+
const lastKey = breadList?.slice(-1)?.[0]?.url;
|
|
107
|
+
localStorage.setItem(
|
|
108
|
+
localStorageKey,
|
|
109
|
+
JSON.stringify({
|
|
110
|
+
[lastKey]: breadList,
|
|
111
|
+
}),
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
localStorage.removeItem(localStorageKey);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, [useCache, useMemory, breadList]);
|
|
119
|
+
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (!useCache) {
|
|
122
|
+
const routerArr = [];
|
|
123
|
+
flatten(children)?.forEach((props) => {
|
|
124
|
+
routerArr.push({
|
|
125
|
+
path: props.path === '/' ? match?.path : props.path,
|
|
126
|
+
name: props.name,
|
|
127
|
+
query: props.query,
|
|
128
|
+
...(props.routerItemHide ? { routerItemHide: props.routerItemHide } : {}),
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const breadCrumbList = [];
|
|
133
|
+
routerArr?.filter((routeObj) => {
|
|
134
|
+
const { path } = routeObj || {};
|
|
135
|
+
const pathObj = matchPath(pathname, { path });
|
|
136
|
+
if (pathObj) {
|
|
137
|
+
breadCrumbList.push({
|
|
138
|
+
...pathObj,
|
|
139
|
+
...(routeObj || {}),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
breadCrumbList.sort((a, b) => {
|
|
145
|
+
return a.path.length - b.path.length;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
breadCrumbList?.map((item) => {
|
|
149
|
+
const querySet = new Set();
|
|
150
|
+
let curQuery = [];
|
|
151
|
+
item.query?.map((item1) => {
|
|
152
|
+
const curKey = Object.keys(item1)[0];
|
|
153
|
+
const sourceKey = Object.values(item1)[0];
|
|
154
|
+
curQuery.push(curKey + '=' + searchObj[sourceKey]);
|
|
155
|
+
querySet.add(curKey);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// const matched = matchPath(pathname, { path: item.path, exact: true });
|
|
159
|
+
if (defaultSearch?.length) {
|
|
160
|
+
defaultSearch.forEach((defaultKey) => {
|
|
161
|
+
if (!querySet.has(defaultKey)) {
|
|
162
|
+
if (searchObj[defaultKey]) {
|
|
163
|
+
curQuery.push(`${defaultKey}=${searchObj[defaultKey]}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (curQuery?.length) {
|
|
169
|
+
item.url += '?' + curQuery.join('&');
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
setBreadList(breadCrumbList);
|
|
173
|
+
}
|
|
174
|
+
}, [pathname]);
|
|
175
|
+
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
const routerArr = [];
|
|
178
|
+
flatten(children)?.forEach((props) => {
|
|
179
|
+
routerArr.push({
|
|
180
|
+
path: props.path === '/' ? match?.path : props.path,
|
|
181
|
+
name: props.name,
|
|
182
|
+
query: props.query,
|
|
183
|
+
...(props.routerItemHide ? { routerItemHide: props.routerItemHide } : {}),
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (useCache) {
|
|
188
|
+
if (pathname) {
|
|
189
|
+
const curRoute = routerArr?.find((item) => {
|
|
190
|
+
const matched = matchPath(pathname, { path: item.path, exact: true });
|
|
191
|
+
if (matched) {
|
|
192
|
+
return item;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
const routeSort = routerArr.sort((a, b) => {
|
|
196
|
+
return a.path.length - b.path.length;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const href = pathname + search;
|
|
200
|
+
// 获取最原始的第一层级数据
|
|
201
|
+
const isIndex = matchPath(pathname, { path: routeSort?.[0]?.path, exact: true });
|
|
202
|
+
|
|
203
|
+
// 如果在缓存中默认取
|
|
204
|
+
if (useMemory && useCache) {
|
|
205
|
+
let curStorageInfo = localStorage.getItem(routeSort?.[0]?.path);
|
|
206
|
+
if (typeof curStorageInfo === 'string') {
|
|
207
|
+
curStorageInfo = JSON.parse(curStorageInfo);
|
|
208
|
+
if (curStorageInfo && curStorageInfo[href]) {
|
|
209
|
+
breadCacheList = curStorageInfo[href];
|
|
210
|
+
}
|
|
211
|
+
if (memoryHandle && typeof memoryHandle === 'function') {
|
|
212
|
+
breadCacheList = memoryHandle({ routeArr: routeSort, href });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 如果是第一层路由例如列表, 查看是否已经在缓存中了
|
|
218
|
+
const indexInfo = isIndex
|
|
219
|
+
? breadCacheList?.find((item) => item.path === pathname)
|
|
220
|
+
: undefined;
|
|
221
|
+
if (isIndex && !search) {
|
|
222
|
+
breadCacheList = [{ ...curRoute, url: href }];
|
|
223
|
+
} else if (indexInfo) {
|
|
224
|
+
// 如果已经在缓存中了 则更新url 说明search发生变化
|
|
225
|
+
indexInfo.url = href;
|
|
226
|
+
} else {
|
|
227
|
+
const hasIn = breadCacheList?.find((item) => item.url === href);
|
|
228
|
+
if (!hasIn) {
|
|
229
|
+
breadCacheList.push({ ...curRoute, url: href });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
setBreadList(JSON.parse(JSON.stringify(breadCacheList)));
|
|
234
|
+
} catch (e) {
|
|
235
|
+
console.log('e', e);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}, [pathname, search, useCache]);
|
|
240
|
+
|
|
241
|
+
const onlyTwoLevels = breadList?.length === 2;
|
|
242
|
+
|
|
243
|
+
const breadClick = (breadIndex) => {
|
|
244
|
+
if (useCache) {
|
|
245
|
+
const breadListTemp = [...breadList];
|
|
246
|
+
breadListTemp.splice(breadIndex + 1);
|
|
247
|
+
breadCacheList = breadListTemp;
|
|
248
|
+
setBreadList(breadListTemp);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// 当前隐藏
|
|
253
|
+
const hideCurrentBreadCrumb = useMemo(() => {
|
|
254
|
+
if (breadList?.length) {
|
|
255
|
+
const curBread = breadList.slice(-1)?.[0] || {};
|
|
256
|
+
if (typeof curBread.routerItemHide === 'function') {
|
|
257
|
+
return curBread.routerItemHide(location);
|
|
258
|
+
}
|
|
259
|
+
return curBread.routerItemHide;
|
|
260
|
+
}
|
|
261
|
+
}, [breadList]);
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<LocaleReceiver componentName="TntdBreadCrumb">
|
|
265
|
+
{(locale, localeCode) => {
|
|
266
|
+
const I18N = !!Object.keys(locale).length ? locale : (mapLocale[localeCode] || mapLocale[getLang()]);
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
{(breadList?.length > 1 || showHeader) && !forceNoHeader && !hideCurrentBreadCrumb && (
|
|
270
|
+
<div className={`page-global-header bread-crumb-head ${curVersion}`}>
|
|
271
|
+
{BreadCrumbCustom &&
|
|
272
|
+
!!breadList?.length &&
|
|
273
|
+
BreadCrumbCustom(breadList, getParams(searchObj))}
|
|
274
|
+
{!(BreadCrumbCustom && BreadCrumbCustom(breadList)) && (
|
|
275
|
+
<Breadcrumb
|
|
276
|
+
separator={!onlyTwoLevels ? separator || '>' : ' '}
|
|
277
|
+
className="c-breadcrumb"
|
|
278
|
+
{...(BreadCrumbPrototype || {})}
|
|
279
|
+
>
|
|
280
|
+
{breadList?.map((bread, i) => {
|
|
281
|
+
const { url } = bread;
|
|
282
|
+
let dom = bread?.name;
|
|
283
|
+
if (breadCrumbCustomName && typeof breadCrumbCustomName === 'function') {
|
|
284
|
+
dom =
|
|
285
|
+
breadCrumbCustomName({
|
|
286
|
+
breadList,
|
|
287
|
+
level: i + 1,
|
|
288
|
+
path: url,
|
|
289
|
+
name: bread?.name,
|
|
290
|
+
pathInfo: bread,
|
|
291
|
+
}) || dom;
|
|
292
|
+
}
|
|
293
|
+
if (onlyTwoLevels && i === 0) {
|
|
294
|
+
dom = (
|
|
295
|
+
<>
|
|
296
|
+
<Icon type="left" className="go-back" />
|
|
297
|
+
{I18N.src.index.fanHui}</>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
return (
|
|
301
|
+
<Breadcrumb.Item key={url}>
|
|
302
|
+
{url && i !== breadList?.length - 1 ? (
|
|
303
|
+
<Link
|
|
304
|
+
onClick={() => {
|
|
305
|
+
breadClick(i);
|
|
306
|
+
}}
|
|
307
|
+
to={url}
|
|
308
|
+
>
|
|
309
|
+
{dom}
|
|
310
|
+
</Link>
|
|
311
|
+
) : (
|
|
312
|
+
dom
|
|
313
|
+
)}
|
|
314
|
+
</Breadcrumb.Item>
|
|
315
|
+
);
|
|
316
|
+
})}
|
|
317
|
+
</Breadcrumb>
|
|
318
|
+
)}
|
|
319
|
+
</div>
|
|
320
|
+
)}
|
|
321
|
+
{!!useCache && (
|
|
322
|
+
<div key={location?.pathname + (location?.search || '')}> {children || null}</div>
|
|
323
|
+
)}
|
|
324
|
+
{!useCache && (children || null)}
|
|
325
|
+
</>
|
|
326
|
+
)
|
|
327
|
+
}}
|
|
328
|
+
</LocaleReceiver>
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
};
|
package/src/index.less
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.bread-crumb-head {
|
|
2
|
+
height: 40px;
|
|
3
|
+
padding: 0 20px;
|
|
4
|
+
line-height: 40px;
|
|
5
|
+
background: #fff;
|
|
6
|
+
border: none;
|
|
7
|
+
.h2 {
|
|
8
|
+
font-size: 14px;
|
|
9
|
+
}
|
|
10
|
+
.c-breadcrumb {
|
|
11
|
+
height: 40px;
|
|
12
|
+
line-height: 40px;
|
|
13
|
+
> span {
|
|
14
|
+
font-size: 14px;
|
|
15
|
+
}
|
|
16
|
+
.go-back {
|
|
17
|
+
margin-right: 2px;
|
|
18
|
+
}
|
|
19
|
+
.ant-breadcrumb-separator {
|
|
20
|
+
margin: 0 6px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
.bread-crumb-body {
|
|
25
|
+
height: ~'calc(100vh - 90px)';
|
|
26
|
+
padding: 16px 20px;
|
|
27
|
+
overflow: auto;
|
|
28
|
+
}
|