Nuxt3页面过渡onLeave系列钩子失效问题求助
Nuxt3 pageTransition离开钩子不触发的解决方案
问题场景
我在Nuxt3中尝试纯通过JavaScript钩子实现页面过渡,无需依赖CSS基础过渡。当前页面的进入类钩子(onBeforeEnter、onEnter、onAfterEnter)都能正常工作,但添加离开类钩子(onBeforeLeave、onLeave、onAfterLeave)后完全没响应,比如onLeave里的console.log根本不输出。
我的配置代码如下(当前页面):
<script setup lang="ts"> definePageMeta({ pageTransition: { name: 'custom-flip', mode: 'out-in', onBeforeEnter: (el) => { console.log('Before enter...') }, onEnter: (el, done) => {}, onAfterEnter: (el) => {}, onBeforeLeave: (el) => {}, onLeave: (el, done) => { console.log('this is not logging to the console...') }, onAfterLeave: (el) => {} } }) </script>
核心原因
你使用了mode: 'out-in'模式,这种模式下离开钩子属于要被替换的旧页面,而非当前正在进入的新页面。Nuxt会先触发旧页面的离开钩子,完成过渡后再执行新页面的进入钩子,所以把离开钩子写在新页面里自然不会被触发。
具体解决步骤
1. 将离开钩子移到旧页面的配置中
比如你从PageA跳转到PageB,把离开类钩子放在PageA的definePageMeta里:
// PageA的<script setup> definePageMeta({ pageTransition: { name: 'custom-flip', mode: 'out-in', onBeforeLeave: (el) => { console.log('旧页面即将离开') }, onLeave: (el, done) => { console.log('旧页面离开中') // 必须调用done()结束过渡,否则会卡住后续流程 done() }, onAfterLeave: (el) => { console.log('旧页面已离开') } } })
PageB只保留进入类钩子即可,同时可以在这里实现你需要的黑色矩形高度缩减动画:
// PageB的<script setup> definePageMeta({ pageTransition: { name: 'custom-flip', mode: 'out-in', onBeforeEnter: (el) => { console.log('新页面即将进入') }, onEnter: (el, done) => { // 实现黑色矩形高度缩减动画 const blackRect = el.querySelector('.black-rect') if (blackRect) { blackRect.style.height = '100vh' // 用requestAnimationFrame确保样式生效后再触发过渡 requestAnimationFrame(() => { blackRect.style.transition = 'height 0.6s ease' blackRect.style.height = '0' // 动画结束后调用done() setTimeout(done, 600) }) } else { done() } }, onAfterEnter: (el) => { console.log('新页面已进入') } } })
2. 禁用CSS过渡(符合纯JS需求)
如果你完全不需要依赖CSS过渡,记得添加css: false,避免Nuxt自动加载对应name的CSS类,干扰JS钩子的执行:
pageTransition: { name: 'custom-flip', mode: 'out-in', css: false, // 禁用默认CSS过渡 // ... 钩子配置 }
3. 全局配置(可选)
如果所有页面的过渡逻辑一致,可以在nuxt.config.ts里全局配置,无需每个页面单独编写:
export default defineNuxtConfig({ app: { pageTransition: { name: 'custom-flip', mode: 'out-in', css: false, onBeforeEnter: (el) => { /* 全局进入前逻辑 */ }, onEnter: (el, done) => { /* 全局进入中逻辑 */ }, onBeforeLeave: (el) => { /* 全局离开前逻辑 */ }, onLeave: (el, done) => { /* 全局离开中逻辑 */ } } } })
内容的提问来源于stack exchange,提问作者aaron lejeune
相关产品推荐
相关产品推荐

