You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:42:52