feat(布局): 在主布局中集成标签页组件

- 在面包屑导航下方添加 TabBar 组件
- 实现路由变化时自动添加标签页
- 首页标签自动设置为不可关闭
- 添加必要的依赖项导入
- 完善标签页与路由的联动机制
This commit is contained in:
gaoziman 2025-11-07 22:36:39 +08:00
parent 2d63d8d5e4
commit e53464eed4

View File

@ -3,22 +3,23 @@ import { Switch, Route, Redirect, useHistory } from 'react-router-dom';
import { Layout, Menu, Breadcrumb, Spin } from '@arco-design/web-react';
import cs from 'classnames';
import {
IconDashboard,
IconList,
IconUser,
IconMenuFold,
IconMenuUnfold,
} from '@arco-design/web-react/icon';
import { useSelector } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import qs from 'query-string';
import NProgress from 'nprogress';
import Navbar from './components/NavBar';
import Footer from './components/Footer';
import TabBar from './components/TabBar';
import useRoute, { IRoute } from '@/routes';
import { isArray } from './utils/is';
import useLocale from './utils/useLocale';
import getUrlParams from './utils/getUrlParams';
import lazyload from './utils/lazyload';
import { GlobalState } from './store';
import { TabItem } from './types/tabs';
import styles from './style/layout.module.less';
const MenuItem = Menu.Item;
@ -50,10 +51,8 @@ function NotFound() {
function getIconFromKey(key) {
switch (key) {
case 'dashboard':
return <IconDashboard className={styles.icon} />;
case 'list':
return <IconList className={styles.icon} />;
case 'user-management':
return <IconUser className={styles.icon} />;
default:
return <div className={styles['icon-empty']} />;
}
@ -89,6 +88,7 @@ function getFlattenRoutes(routes) {
function PageLayout() {
const urlParams = getUrlParams();
const history = useHistory();
const dispatch = useDispatch();
const pathname = history.location.pathname;
const currentComponent = qs.parseUrl(pathname).url.slice(1);
const locale = useLocale();
@ -210,7 +210,26 @@ function PageLayout() {
const routeConfig = routeMap.current.get(pathname);
setBreadCrumb(routeConfig || []);
updateMenuStatus();
}, [pathname]);
// 自动添加标签页
const currentRoute = flattenRoutes.find(
(route) => pathname === `/${route.key}`
);
if (currentRoute) {
const isFirstRoute = currentRoute.key === defaultRoute;
const newTab: TabItem = {
key: currentRoute.key,
name: currentRoute.name,
path: pathname,
closable: !isFirstRoute, // 首页标签不可关闭
};
dispatch({
type: 'tabs/addTab',
payload: newTab,
});
}
}, [pathname, flattenRoutes, defaultRoute, dispatch]);
return (
<Layout className={styles.layout}>
@ -267,6 +286,7 @@ function PageLayout() {
</Breadcrumb>
</div>
)}
<TabBar />
<Content>
<Switch>
{flattenRoutes.map((route, index) => {