SvelteKit页面过渡:如何实现类似exitBeforeEnter的效果?
SvelteKit/svelte-motion 实现"exitBeforeEnter"式页面过渡
方案1:原生Svelte + SvelteKit 手动控制过渡顺序
SvelteKit默认页面切换时,新旧页面的过渡动画会同时执行。要实现先完成当前页的out过渡再启动新页的in过渡,可以在根布局(+layout.svelte)中手动跟踪页面切换状态,配合定时器匹配动画时长:
<script> import { page } from '$app/stores'; import { fly } from 'svelte/transition'; let currentPath = $page.url.pathname; let isExiting = false; let showNewPage = false; // 监听页面路径变化 $: if ($page.url.pathname !== currentPath) { isExiting = true; // 等待当前页out动画结束(对应你的out动画时长100ms) setTimeout(() => { currentPath = $page.url.pathname; showNewPage = true; // 新页in动画完成后重置状态 setTimeout(() => { isExiting = false; showNewPage = false; }, 300); // 对应in动画时长300ms }, 100); } </script> {#if !isExiting} {#if showNewPage} <main in:fly={{ y: 100, duration: 300 }}> <slot /> </main> {:else} <main out:fly={{ y: -100, duration: 100 }}> <slot /> </main> {/if} {/if}
方案2:使用svelte-motion的AnimatePresence(推荐)
svelte-motion完全对齐Framer Motion的API,其AnimatePresence组件内置exitBeforeEnter属性,直接满足你的需求,无需手动管理定时器:
<script> import { page } from '$app/stores'; import { motion, AnimatePresence } from 'svelte-motion'; </script> <AnimatePresence exitBeforeEnter> <motion.main key={$page.url.pathname} initial={{ y: 100 }} animate={{ y: 0 }} exit={{ y: -100 }} transition={{ duration: 0.3 }} exitTransition={{ duration: 0.1 }} > <slot /> </motion.main> </AnimatePresence>
关键说明:
key属性必须绑定到页面的唯一标识(如路径),让AnimatePresence能识别页面切换事件;exitBeforeEnter开启后,组件会等待上一个元素的exit动画完全结束,再渲染新元素并执行initial→animate的过渡;- 可以通过
transition和exitTransition分别控制进入、退出动画的时长,和你原本的fly动画参数对应。
内容的提问来源于stack exchange,提问作者Jozefini
相关产品推荐
相关产品推荐

