From eae1bd2c180792b5f0f5ef09460da50a90b2c9da Mon Sep 17 00:00:00 2001 From: ylj20011123 Date: Thu, 11 Sep 2025 10:47:33 +0800 Subject: [PATCH] =?UTF-8?q?tab=E5=9B=9E=E6=98=BE=E9=A1=B5=E9=9D=A2=20?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PageTransition/index.tsx | 20 +++++++- src/layouts/BasicLayout.tsx | 64 ++++++++++++++++++++----- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/components/PageTransition/index.tsx b/src/components/PageTransition/index.tsx index cb177f8..cbf8ab3 100644 --- a/src/components/PageTransition/index.tsx +++ b/src/components/PageTransition/index.tsx @@ -42,12 +42,28 @@ const PageTransition: React.FC = ({ }; // 简化版本 - 仅使用CSS动画 -export const SimplePageTransition: React.FC<{ children: React.ReactNode; className?: string }> = ({ +export const SimplePageTransition: React.FC<{ + children: React.ReactNode; + className?: string; + enableAnimation?: boolean; + onAnimationEnd?: () => void; +}> = ({ children, className = '', + enableAnimation = true, + onAnimationEnd, }) => { + const handleAnimationEnd = () => { + if (enableAnimation && onAnimationEnd) { + onAnimationEnd(); + } + }; + return ( -
+
{children}
); diff --git a/src/layouts/BasicLayout.tsx b/src/layouts/BasicLayout.tsx index f38739d..96b76ad 100644 --- a/src/layouts/BasicLayout.tsx +++ b/src/layouts/BasicLayout.tsx @@ -93,6 +93,7 @@ const BasicLayout: React.FC = (props) => { const [activeKey, setActiveKey] = useState(location?.pathname || '/') + const [animatedPages, setAnimatedPages] = useState>(new Set()); const menuDataRef = useRef([]); const { formatMessage } = useIntl(); @@ -141,6 +142,13 @@ const BasicLayout: React.FC = (props) => { // 改变panes const handleTabsPanes = (payload: any): void => { if (dispatch) { + // 检查是否为新页面 + const isNewPage = !tabsPanes.some(tab => tab.path === payload.path); + if (isNewPage) { + // 标记新页面需要播放动画 + setAnimatedPages(prev => new Set(prev).add(payload.path)); + } + dispatch({ type: 'global/changeTabsRoutes', payload: { data: payload, action: 'add' }, @@ -161,6 +169,13 @@ const BasicLayout: React.FC = (props) => { history.push(nextkey || '/') setActiveKey(nextkey) + // 从动画记录中移除关闭的页面 + setAnimatedPages(prev => { + const newSet = new Set(prev); + newSet.delete(targetKey as string); + return newSet; + }); + // 缓存路由栈数据 dispatch({ type: 'global/changeTabsRoutes', @@ -1007,6 +1022,13 @@ const BasicLayout: React.FC = (props) => { break; } + // 从动画记录中移除关闭的页面 + setAnimatedPages(prev => { + const newSet = new Set(prev); + closeTabKeys.forEach(key => newSet.delete(key)); + return newSet; + }); + dispatch({ type: 'global/changeTabsRoutes', payload: { data: closeTabKeys, action: 'remove' }, @@ -1036,19 +1058,35 @@ const BasicLayout: React.FC = (props) => { } moreIcon={} > - {tabsPanes && tabsPanes.map((item: tabsRoute) => - - - - - {item.children} - - - - ) - } + {tabsPanes && tabsPanes.map((item: tabsRoute) => { + const shouldAnimate = animatedPages.has(item.path); + + return ( + + { + // 动画播放完成后,移除动画标记 + setAnimatedPages(prev => { + const newSet = new Set(prev); + newSet.delete(item.path); + return newSet; + }); + }} + > + + + {item.children} + + + + + ); + })} {/* 不要标签栏,删除tabs的代码,使用下方的代码就可以 */} {/*