forked from wangziqi/gongxue-base
fix(layout): use controlled sidebar openKeys to preserve manual expand/collapse across navigation
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
|
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { Layout, Menu, Button, Avatar, Dropdown, Drawer, Grid } from 'antd';
|
import { Layout, Menu, Button, Avatar, Dropdown, Drawer, Grid } from 'antd';
|
||||||
import {
|
import {
|
||||||
@@ -123,6 +123,8 @@ const allMenuItems: MenuItemType[] = [
|
|||||||
const MainLayout: React.FC = () => {
|
const MainLayout: React.FC = () => {
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
|
const [openKeys, setOpenKeys] = useState<string[]>([]);
|
||||||
|
const prevPathname = useRef('');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const user = useMemo(() => JSON.parse(localStorage.getItem('user') || '{}'), []);
|
const user = useMemo(() => JSON.parse(localStorage.getItem('user') || '{}'), []);
|
||||||
@@ -185,7 +187,20 @@ const MainLayout: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectedKeys = useMemo(() => findSelectedKeys(menuItems, location.pathname), [menuItems, location.pathname]);
|
const selectedKeys = useMemo(() => findSelectedKeys(menuItems, location.pathname), [menuItems, location.pathname]);
|
||||||
const openKeys = useMemo(() => findOpenKeys(menuItems, location.pathname), [menuItems, location.pathname]);
|
// 路径变化时同步展开的菜单(不干扰用户手动展开/收起)
|
||||||
|
useEffect(() => {
|
||||||
|
if (location.pathname !== prevPathname.current) {
|
||||||
|
prevPathname.current = location.pathname;
|
||||||
|
setOpenKeys(findOpenKeys(menuItems, location.pathname));
|
||||||
|
}
|
||||||
|
}, [location.pathname, menuItems]);
|
||||||
|
|
||||||
|
const handleOpenChange = useCallback((keys: string[]) => {
|
||||||
|
// 只保留最新打开的一个子菜单
|
||||||
|
const latestKey = keys[keys.length - 1];
|
||||||
|
setOpenKeys(latestKey ? [latestKey] : []);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const transformToMenuItems = (items: MenuItemType[]): any[] => {
|
const transformToMenuItems = (items: MenuItemType[]): any[] => {
|
||||||
@@ -201,7 +216,8 @@ const MainLayout: React.FC = () => {
|
|||||||
theme="light"
|
theme="light"
|
||||||
mode="inline"
|
mode="inline"
|
||||||
selectedKeys={selectedKeys}
|
selectedKeys={selectedKeys}
|
||||||
defaultOpenKeys={openKeys}
|
openKeys={openKeys}
|
||||||
|
onOpenChange={handleOpenChange}
|
||||||
items={transformToMenuItems(menuItems)}
|
items={transformToMenuItems(menuItems)}
|
||||||
onClick={({ key }) => handleMenuClick(key)}
|
onClick={({ key }) => handleMenuClick(key)}
|
||||||
style={{ border: 'none' }}
|
style={{ border: 'none' }}
|
||||||
|
|||||||
Reference in New Issue
Block a user