在NextJS中借助Framer Motion实现旧路由滑出、新路由滑入效果
问题原因
你当前退场动画不生效的核心原因是AnimatePresence组件无法识别路由切换时的组件变更,无法触发卸载阶段的exit动画。AnimatePresence依赖直接子元素的唯一key判断元素是否需要执行退场逻辑,你当前未给Component绑定唯一标识,因此只有入场动画可以正常触发。
修复步骤
1. 修改_app.js配置
首先引入路由钩子给页面组件绑定唯一key,同时可以配置AnimatePresence的mode属性控制动画时序:
import { useRouter } from 'next/router' import { AnimatePresence } from 'framer-motion' function MyApp({ Component, pageProps }) { const router = useRouter() return ( {/* mode="wait"表示等待旧页面完全退场后再渲染新页面 */} <AnimatePresence mode="wait"> <Component {...pageProps} key={router.asPath} /> </AnimatePresence> ) }
如果你使用的是Next.js 13+ App Router,将
useRouter替换为usePathname获取路径作为key即可。
2. 可选:优化动画配置
你当前的入场和退场动画都是从顶部滑入/滑出,如果需要区分方向(旧页面从底部滑出,新页面从顶部滑入)可以调整变体配置:
const slide = { hidden: { y: '-100%', opacity: 0, }, visible: { y: 0, opacity: 1, transition: { duration: 0.3, ease: "easeOut" } }, exit: { y: '100%', opacity: 0, transition: { duration: 0.2, ease: "easeIn" } } }
调整后对应修改页面组件的exit属性即可:
const Home = () =>{ return ( <motion.div initial='hidden' animate='visible' exit='exit' variants={slide}> Home Component </motion.div> ) }
修改完成后路由切换时就会同时触发旧页面退场、新页面入场的动画效果。
内容的提问来源于stack exchange,提问作者s.khan
相关产品推荐
相关产品推荐

