Nuxt3布局过渡钩子异常:onEnter提前于onLeave结束启动
解决Nuxt3布局过渡中onEnter提前触发的问题
问题原因
Nuxt3的布局过渡默认采用并行执行逻辑:离开动画(onLeave)和进入动画(onEnter)会同时启动,这就是你控制台输出leave start -> enter start -> leave end -> enter end的直接原因。
解决方案
1. 启用过渡的in-out模式
在layoutTransition配置中添加mode: 'in-out',该模式会强制等待离开动画完全结束后,再触发进入动画。
修改后的页面元配置:
definePageMeta({ scrollToTop: false, layout: "default", layoutTransition: { name: "layout-transition", css: false, mode: 'in-out', // 关键配置:等待离开动画结束再启动进入动画 onLeave: async (el, done) => { console.log("leave start") await onLeaveAnimation() console.log("leave end") done() }, onEnter: async (el, done) => { console.log("enter start") await onEnterAnimation() console.log("enter end") done() } }, });
2. 确保GSAP动画函数正确返回Promise
GSAP时间线本身支持Promise链式调用,无需多次await单个动画步骤,直接返回完整时间线即可让await等待整个动画序列完成。
修正后的动画函数示例:
async function onLeaveAnimation() { const timeline = gsap.timeline() const loadingScreen: HTMLElement | null = document.getElementById("loading-screen"); const letters: NodeListOf<Element> | null = document.querySelectorAll(".text-loading-title > span"); const lettersOutAnimation = { opacity: 0, transform: "translateY(-100%)", stagger: 0.05, ease: "ease-out", } const positionAnimation = { transform: "translateY(-100%)", duration: 0.5, ease: "ease-in-out", } const sizeAnimation = { height: "0vh", duration: 0, } // 链式构建完整时间线 timeline.to(letters, lettersOutAnimation) .to(loadingScreen, positionAnimation) .set(loadingScreen, sizeAnimation); // 返回时间线,让await等待所有动画完成 return timeline; }
效果验证
修改完成后,控制台输出会变为预期的顺序:
leave start leave end enter start enter end
内容的提问来源于stack exchange,提问作者MVT KVM
相关产品推荐
相关产品推荐

