提交 7831604d 作者: 郁骅焌

刷新选中tab

上级 cae239e6
...@@ -23,6 +23,9 @@ export default defineConfig({ ...@@ -23,6 +23,9 @@ export default defineConfig({
targets: { targets: {
ie: 11, ie: 11,
}, },
plugins: ['@alitajs/keep-alive'],
// 缓存页面
keepalive: ['/demo/crud', '/system/role'],
// umi routes: https://umijs.org/docs/routing // umi routes: https://umijs.org/docs/routing
routes: [ routes: [
{ {
...@@ -87,19 +90,10 @@ export default defineConfig({ ...@@ -87,19 +90,10 @@ export default defineConfig({
}, },
], ],
}, },
{
component: './404',
},
], ],
}, },
{
component: './404',
},
], ],
}, },
{
component: './404',
},
], ],
// Theme for antd: https://ant.design/docs/react/customize-theme-cn // Theme for antd: https://ant.design/docs/react/customize-theme-cn
theme: { theme: {
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
"not ie <= 10" "not ie <= 10"
], ],
"dependencies": { "dependencies": {
"@alitajs/keep-alive": "^2.3.9",
"@ant-design/icons": "^4.0.0", "@ant-design/icons": "^4.0.0",
"@ant-design/pro-layout": "^5.0.8", "@ant-design/pro-layout": "^5.0.8",
"@ant-design/pro-table": "2.2.1", "@ant-design/pro-table": "2.2.1",
...@@ -62,6 +63,7 @@ ...@@ -62,6 +63,7 @@
"path-to-regexp": "2.4.0", "path-to-regexp": "2.4.0",
"qs": "^6.9.0", "qs": "^6.9.0",
"react": "^16.8.6", "react": "^16.8.6",
"react-activation": "^0.5.0",
"react-dom": "^16.8.6", "react-dom": "^16.8.6",
"react-helmet-async": "^1.0.4", "react-helmet-async": "^1.0.4",
"umi": "3.1.1", "umi": "3.1.1",
......
import React, { useState, useEffect, useImperativeHandle } from 'react' import React, { useState, useEffect, useImperativeHandle } from 'react';
import { Tabs } from 'antd' import { Tabs, Menu, Dropdown, Button } from 'antd';
import { useLocation, history } from "umi" import { ReloadOutlined } from '@ant-design/icons';
import './style.less' import { useLocation, history, dropByCacheKey } from 'umi';
import './style.less';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const TabBar = (props, ref) => { const TabBar = (props, ref) => {
const location = useLocation();
const location = useLocation() const { pathname } = location;
const { pathname } = location const {
const { currentUser: { menuTree } } = props currentUser: { menuTree },
} = props;
const [panes, setPanes] = useState([ const [panes, setPanes] = useState([
{ title: '首页', key: '/home', closable: false }, { title: '首页', key: '/home', closable: false },
...@@ -26,95 +28,94 @@ const TabBar = (props, ref) => { ...@@ -26,95 +28,94 @@ const TabBar = (props, ref) => {
// { title: '测试标签10', key: '11' }, // { title: '测试标签10', key: '11' },
// { title: '测试标签11', key: '12' }, // { title: '测试标签11', key: '12' },
// { title: '测试标签12', key: '13' } // { title: '测试标签12', key: '13' }
]) ]);
const [activeKey, setActiveKey] = useState('') const [activeKey, setActiveKey] = useState('');
const [allPath, setAllPath] = useState([]) const [allPath, setAllPath] = useState([]);
const checkPaneExist = (path) => { const checkPaneExist = (path) => {
let isExist = false let isExist = false;
for (let i = 0; i < panes.length; i++) { for (let i = 0; i < panes.length; i++) {
if (panes[i].key === path) { if (panes[i].key === path) {
isExist = true isExist = true;
break break;
} }
} }
if (!isExist) { if (!isExist) {
const p = allPath.find((item) => { const p = allPath.find((item) => {
return item.path === path return item.path === path;
}) });
if (p) { if (p) {
const newPanes = panes.slice() const newPanes = panes.slice();
newPanes.push({ newPanes.push({
title: p.name, title: p.name,
key: path key: path,
}) });
setPanes(newPanes) setPanes(newPanes);
}
} }
} }
};
// 初始化 // 初始化
useEffect(() => { useEffect(() => {
const list = [];
const list = []
const loopPath = (arr) => { const loopPath = (arr) => {
arr.forEach(item => { arr.forEach((item) => {
list.push(item); list.push(item);
if (item.hasSun) { if (item.hasSun) {
const clist = item.children.slice() const clist = item.children.slice();
loopPath(clist) loopPath(clist);
}
})
} }
loopPath(menuTree) });
setAllPath(list) };
loopPath(menuTree);
setAllPath(list);
let isExist = false let isExist = false;
for (let i = 0; i < panes.length; i++) { for (let i = 0; i < panes.length; i++) {
if (panes[i].key === pathname) { if (panes[i].key === pathname) {
isExist = true isExist = true;
break break;
} }
} }
if (!isExist) { if (!isExist) {
const p = list.find((item) => { const p = list.find((item) => {
return item.path === pathname return item.path === pathname;
}) });
if (p) { if (p) {
const newPanes = panes.slice() const newPanes = panes.slice();
newPanes.push({ newPanes.push({
title: p.name, title: p.name,
key: pathname key: pathname,
}) });
setPanes(newPanes) setPanes(newPanes);
} }
} }
setActiveKey(pathname) setActiveKey(pathname);
}, []) }, []);
const onChange = (activekey, fromMenu) => { const onChange = (activekey, fromMenu) => {
if (activekey !== activeKey) { if (activekey !== activeKey) {
setTimeout(() => { // setTimeout(() => {
setActiveKey(activekey) setActiveKey(activekey);
}, 200) // }, 200)
if (!fromMenu) { if (!fromMenu) {
history.push(activekey) history.push(activekey);
} else { } else {
checkPaneExist(activekey) checkPaneExist(activekey);
}
} }
} }
};
const remove = targetKey => { const remove = (targetKey) => {
let lastActiveKey = '/home' let lastActiveKey = '/home';
let lastIndex; let lastIndex;
panes.forEach((pane, i) => { panes.forEach((pane, i) => {
if (pane.key === targetKey) { if (pane.key === targetKey) {
lastIndex = i - 1; lastIndex = i - 1;
} }
}); });
const lastPanes = panes.filter(pane => pane.key !== targetKey); const lastPanes = panes.filter((pane) => pane.key !== targetKey);
if (lastPanes.length && activeKey === targetKey) { if (lastPanes.length && activeKey === targetKey) {
if (lastIndex >= 0) { if (lastIndex >= 0) {
lastActiveKey = lastPanes[lastIndex].key; lastActiveKey = lastPanes[lastIndex].key;
...@@ -124,11 +125,11 @@ const TabBar = (props, ref) => { ...@@ -124,11 +125,11 @@ const TabBar = (props, ref) => {
} else { } else {
lastActiveKey = lastPanes[lastPanes.length - 1].key; lastActiveKey = lastPanes[lastPanes.length - 1].key;
} }
setTimeout(() => { // setTimeout(() => {
setActiveKey(lastActiveKey) setActiveKey(lastActiveKey);
}, 200) // }, 200)
setPanes(lastPanes) setPanes(lastPanes);
history.push(lastActiveKey) history.push(lastActiveKey);
}; };
const onEdit = (targetKey, action) => { const onEdit = (targetKey, action) => {
...@@ -137,12 +138,29 @@ const TabBar = (props, ref) => { ...@@ -137,12 +138,29 @@ const TabBar = (props, ref) => {
} }
}; };
// 刷新
const refreshTab = (e) => {
e.preventDefault();
dropByCacheKey(activeKey);
history.push(activeKey);
};
const menu = (
<Menu>
<Menu.Item key="0">
<a onClick={(e) => refreshTab(e)}>刷新</a>
</Menu.Item>
</Menu>
);
// 暴露外部方法
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
onChange onChange,
})) }));
return ( return (
<div className="sage-tabbar"> <div className="sage-tabbar">
<div className="sage-tabbar-left">
<Tabs <Tabs
onChange={onChange} onChange={onChange}
activeKey={activeKey} activeKey={activeKey}
...@@ -151,15 +169,18 @@ const TabBar = (props, ref) => { ...@@ -151,15 +169,18 @@ const TabBar = (props, ref) => {
tabBarGutter={4} tabBarGutter={4}
onEdit={onEdit} onEdit={onEdit}
> >
{ {panes.map((pane) => (
panes.map(pane => (
<TabPane tab={pane.title} key={pane.key} closable={pane.closable} /> <TabPane tab={pane.title} key={pane.key} closable={pane.closable} />
)) ))}
}
</Tabs> </Tabs>
</div> </div>
) <div className="sage-tabbar-right">
<Dropdown overlay={menu} trigger={['click']}>
} <Button className="sage-tabbar-button" icon={<ReloadOutlined />} size="middle" />
</Dropdown>
</div>
</div>
);
};
export default React.forwardRef(TabBar) export default React.forwardRef(TabBar);
.sage-tabbar { .sage-tabbar {
margin: -24px -24px -4px; display: flex;
height: 40px; height: 40px;
margin: -24px -24px -4px;
background: #fff; background: #fff;
.sage-tabbar-left {
flex: 1;
}
.sage-tabbar-right {
flex: 0 0 40px;
.sage-tabbar-button {
float: right;
width: 40px;
height: 100%;
border: none;
}
}
.ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab { .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid #f0f0f0;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
import ProLayout, { DefaultFooter } from '@ant-design/pro-layout'; import ProLayout, { DefaultFooter } from '@ant-design/pro-layout';
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import { Link, useIntl, connect } from 'umi'; import { Link, useIntl, connect, KeepAliveLayout } from 'umi';
import { GithubOutlined } from '@ant-design/icons'; import { GithubOutlined } from '@ant-design/icons';
import { Result, Button } from 'antd'; import { Result, Button } from 'antd';
import Authorized from '@/utils/Authorized'; import Authorized from '@/utils/Authorized';
...@@ -30,8 +30,8 @@ const noMatch = ( ...@@ -30,8 +30,8 @@ const noMatch = (
/** /**
* use Authorized check all menu item * use Authorized check all menu item
*/ */
const menuDataRender = menuList => const menuDataRender = (menuList) =>
menuList.map(item => { menuList.map((item) => {
const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] }; const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] };
return Authorized.check(item.authority, localItem, null); return Authorized.check(item.authority, localItem, null);
}); });
...@@ -62,7 +62,7 @@ const defaultFooterDom = ( ...@@ -62,7 +62,7 @@ const defaultFooterDom = (
/> />
); );
const BasicLayout = props => { const BasicLayout = (props) => {
const { const {
dispatch, dispatch,
children, children,
...@@ -70,13 +70,13 @@ const BasicLayout = props => { ...@@ -70,13 +70,13 @@ const BasicLayout = props => {
location = { location = {
pathname: '/', pathname: '/',
}, },
currentUser currentUser,
} = props; } = props;
/** /**
* constructor * constructor
*/ */
const tabBarRef = useRef() const tabBarRef = useRef();
useEffect(() => { useEffect(() => {
if (dispatch) { if (dispatch) {
...@@ -89,7 +89,7 @@ const BasicLayout = props => { ...@@ -89,7 +89,7 @@ const BasicLayout = props => {
* init variables * init variables
*/ */
const handleMenuCollapse = payload => { const handleMenuCollapse = (payload) => {
if (dispatch) { if (dispatch) {
dispatch({ dispatch({
type: 'global/changeLayoutCollapsed', type: 'global/changeLayoutCollapsed',
...@@ -100,9 +100,9 @@ const BasicLayout = props => { ...@@ -100,9 +100,9 @@ const BasicLayout = props => {
const handlePageChange = ({ pathname }) => { const handlePageChange = ({ pathname }) => {
if (tabBarRef.current) { if (tabBarRef.current) {
tabBarRef.current.onChange(pathname, true) tabBarRef.current.onChange(pathname, true);
}
} }
};
const authorized = getAuthorityFromRouter(props.route.routes, location.pathname || '/') || { const authorized = getAuthorityFromRouter(props.route.routes, location.pathname || '/') || {
authority: undefined, authority: undefined,
...@@ -152,7 +152,7 @@ const BasicLayout = props => { ...@@ -152,7 +152,7 @@ const BasicLayout = props => {
> >
<TabBar ref={tabBarRef} currentUser={currentUser} /> <TabBar ref={tabBarRef} currentUser={currentUser} />
<Authorized authority={authorized.authority} noMatch={noMatch}> <Authorized authority={authorized.authority} noMatch={noMatch}>
{children} <KeepAliveLayout {...props}>{children}</KeepAliveLayout>
</Authorized> </Authorized>
</ProLayout> </ProLayout>
); );
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论