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

Nuxt 3 简单页面过渡不生效 如何用JS钩子实现页面切换动画

Nuxt 3 基于JS钩子实现页面过渡的正确方案

手动在app.vue里给<NuxtPage>套<Transition>的写法无法正常触发钩子,核心原因是Nuxt 3内置了页面、布局层级的过渡封装,不需要手动嵌套额外的Transition组件,按以下步骤配置即可兼容GSAP、Anime.js等JS动画库:

全局基础配置

先在nuxt.config.ts中开启全局页面过渡,关闭CSS过渡模式,指定过渡时序:

export default defineNuxtConfig({
  app: {
    pageTransition: {
      name: 'page',
      mode: 'out-in', // 可根据需求替换为in-out
      css: false // 必选:禁用CSS过渡检测,完全由JS控制动画流程
    }
  }
})

如果需要给单个页面设置独立过渡规则,可在对应页面的definePageMeta中覆盖pageTransition字段,优先级高于全局配置。

全局过渡钩子绑定

直接在<NuxtPage>组件上监听Nuxt暴露的页面过渡事件即可,无需额外包裹Transition:

<!-- app.vue -->
<template>
  <NuxtLayout>
    <NuxtPage
      @page-enter="handlePageEnter"
      @page-leave="handlePageLeave"
      @before-enter="handleBeforeEnter"
      @after-enter="handleAfterEnter"
      @leave-cancelled="handleLeaveCancel"
    />
  </NuxtLayout>
</template>

<script setup>
// 按需引入动画库,以GSAP为例
import gsap from 'gsap'

const handlePageEnter = (el, done) => {
  // 编写进入动画逻辑
  gsap.fromTo(el, 
    { opacity: 0, y: 24 },
    { 
      opacity: 1, 
      y: 0, 
      duration: 0.4,
      ease: 'power2.out',
      onComplete: done // 动画执行完成必须调用done,否则路由会卡住
    }
  )
}

const handlePageLeave = (el, done) => {
  // 编写离开动画逻辑
  gsap.to(el, {
    opacity: 0,
    y: -24,
    duration: 0.3,
    ease: 'power2.in',
    onComplete: done
  })
}

// 以下钩子按需实现即可
const handleBeforeEnter = (el) => {
  // 初始化进入前的DOM状态
}
const handleAfterEnter = (el) => {
  // 进入动画完成后的收尾逻辑
}
const handleLeaveCancel = (el) => {
  // 离开动画被中断(比如快速切换路由)时的重置逻辑
}
</script>

单页面独立过渡写法

不需要全局统一动画时,可直接在单页面内通过definePageMeta配置专属过渡:

<!-- pages/project/myproject.vue -->
<template>
  <div>
    <h1>My Project</h1>
  </div>
</template>

<script setup>
definePageMeta({
  pageTransition: {
    name: 'project-page',
    mode: 'out-in',
    css: false,
    onEnter(el, done) {
      // 该页面专属进入动画
      console.log('进入项目页')
      done()
    },
    onLeave(el, done) {
      // 该页面专属离开动画
      console.log('离开项目页')
      done()
    }
  }
})
</script>

注意事项

  • 禁止手动在<NuxtPage>外层嵌套原生<Transition>组件,会和Nuxt内置的过渡逻辑冲突,导致钩子不触发、DOM重复渲染等问题
  • 使用JS动画必须将css属性设为false,否则Vue会默认等待CSS过渡时长,和JS动画的done回调产生时序冲突
  • 所有JS钩子中,只要声明了done入参,就必须在动画结束时调用,否则路由切换流程会一直挂起
  • 布局过渡的配置逻辑和页面过渡完全一致:在nuxt.config.ts的app.layoutTransition字段配置参数,在<NuxtLayout>组件上监听对应的布局过渡事件即可

内容的提问来源于stack exchange,提问作者bappla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:33:24