Files
toco-react-template/template/src/layout/index.tsx
2024-10-14 18:51:44 +08:00

97 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { setCurrentMenu, setHeadMenus } from '@/app/common';
import { useAppDispatch } from '@/app/hooks';
import SuspenseLayout from '@/components/suspense-layout';
import {
findFirstSubMenu,
findHeadMenuByHeadKey,
findHeadMenuBySideKey,
menuItems,
} from '@/utils/menu';
import { MenuProps } from '@df/toco-ui';
import { useCallback, useEffect } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import Layout from './HeaderAndSider';
// import Layout from './HeaderAndFooter';
export type LayoutProps = {
children?: React.ReactNode;
onHeadMenuSelect?: MenuProps['onSelect'];
onSideMenuSelect?: MenuProps['onSelect'];
};
const LayoutRoot = () => {
const dispatch = useAppDispatch();
const location = useLocation();
const navigate = useNavigate();
// 设置head菜单
useEffect(() => {
dispatch(setHeadMenus(menuItems));
}, [dispatch]);
// 监听路由变化
useEffect(() => {
const key = location.pathname.replace(/^\//, '').replace(/\/$/, '');
const headMenu = findHeadMenuByHeadKey(key);
if (headMenu) {
// 一级页面
dispatch(
setCurrentMenu({
headKey: headMenu.key,
}),
);
} else {
// 非一级页面
const headMenu = findHeadMenuBySideKey(key);
dispatch(
setCurrentMenu({
headKey: headMenu?.key ?? '',
sideKey: key,
}),
);
}
}, [dispatch, location]);
const handleHeadMenuSelect: MenuProps['onSelect'] = useCallback(
({ item, key, keyPath, domEvent }) => {
const headMenu = findHeadMenuByHeadKey(key);
if (!headMenu) {
// 顶部嵌套的菜单即实际点击的sideMenu
navigate(key);
return;
}
if (!headMenu.children?.length) {
// 一级页面
navigate(key);
} else {
// 非一级页面点击一级菜单,主动跳转第一个子页面
const subMenu = findFirstSubMenu(headMenu);
if (subMenu) {
navigate(subMenu.key);
}
}
},
[navigate],
);
const handleSideMenuSelect: MenuProps['onSelect'] = useCallback(
({ item, key, keyPath, domEvent }) => {
navigate(key);
},
[navigate],
);
return (
<Layout
onHeadMenuSelect={handleHeadMenuSelect}
onSideMenuSelect={handleSideMenuSelect}
>
<SuspenseLayout>
<Outlet />
</SuspenseLayout>
</Layout>
);
};
export default LayoutRoot;