如何在页面过渡中使用AnimatePresence且不影响嵌套子元素
解决AnimatePresence影响内部Framer Motion动画的问题
问题根源
你设置的AnimatePresence initial={false}是全局生效的,会强制禁用其所有后代motion组件的初始动画,包括页面内嵌套的其他motion元素,这就是导致后续动画失效的原因。
推荐解决方案:条件化控制页面过渡组件的初始动画
移除AnimatePresence上的initial={false},转而在页面过渡的motion.div上通过状态判断,仅在路由切换时触发初始动画,首次加载时跳过。这样既保留了页面切换的过渡效果,又不会影响内部其他motion组件的动画。
代码实现(Next.js _app.js中)
import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import { AnimatePresence, motion } from 'framer-motion'; export default function App({ Component, pageProps }) { const router = useRouter(); const [isFirstLoad, setIsFirstLoad] = useState(true); useEffect(() => { // 路由初始化完成后,标记为非首次加载 if (router.isReady) { setIsFirstLoad(false); } }, [router.isReady]); return ( <AnimatePresence mode="wait" onExitComplete={() => { window.scrollTo(0, 0); setLoaderVisible(false); }} > {/* 用路由路径作为key,确保路由切换时触发组件卸载/挂载 */} <motion.div key={router.asPath} // 首次加载时跳过初始动画,路由切换时启用 initial={isFirstLoad ? false : { opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ type: 'easeInOut', duration: 0.5 }} > <Component {...pageProps} /> </motion.div> </AnimatePresence> ); }
备选方案:手动覆盖内部组件的初始动画
如果你不想修改AnimatePresence的配置,可以给页面内需要保留初始动画的motion组件,手动指定initial属性(具体状态或true),以此覆盖AnimatePresence的全局禁用规则。
示例:
// 内部嵌套的motion组件,不受AnimatePresence影响 <motion.div initial={{ scale: 0 }} animate={{ scale: 1 }} transition={{ duration: 0.3 }} > 页面内动画元素 </motion.div>
注:此方案需要逐个修改内部motion组件,适合动画数量较少的场景。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

