From 5145c3e4b407486b2c1c3973cea3adce561172c7 Mon Sep 17 00:00:00 2001 From: wangziqi Date: Thu, 9 Jul 2026 16:31:56 +0800 Subject: [PATCH] fix(layout): use controlled sidebar openKeys to preserve manual expand/collapse across navigation --- apps/admin/src/layouts/MainLayout.tsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/apps/admin/src/layouts/MainLayout.tsx b/apps/admin/src/layouts/MainLayout.tsx index a6ad416..249763f 100644 --- a/apps/admin/src/layouts/MainLayout.tsx +++ b/apps/admin/src/layouts/MainLayout.tsx @@ -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 { Layout, Menu, Button, Avatar, Dropdown, Drawer, Grid } from 'antd'; import { @@ -123,6 +123,8 @@ const allMenuItems: MenuItemType[] = [ const MainLayout: React.FC = () => { const [collapsed, setCollapsed] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); + const [openKeys, setOpenKeys] = useState([]); + const prevPathname = useRef(''); const navigate = useNavigate(); const location = useLocation(); 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 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[] => { @@ -201,7 +216,8 @@ const MainLayout: React.FC = () => { theme="light" mode="inline" selectedKeys={selectedKeys} - defaultOpenKeys={openKeys} + openKeys={openKeys} + onOpenChange={handleOpenChange} items={transformToMenuItems(menuItems)} onClick={({ key }) => handleMenuClick(key)} style={{ border: 'none' }}