トランジション
Vue またはネイティブブラウザの View Transitions を使用してページやレイアウト間にトランジションを適用します。
Nuxt は Vue の <Transition>
コンポーネントを活用して、ページやレイアウト間にトランジションを適用します。
ページトランジション
すべてのページに自動トランジションを適用するために、ページトランジションを有効にすることができます。
export default defineNuxtConfig({
app: {
pageTransition: { name: 'page', mode: 'out-in' }
}
})
ページと同様にレイアウトも変更する場合、ここで設定したページトランジションは実行されません。その代わりに、レイアウトトランジションを設定する必要があります。
ページ間にトランジションを追加し始めるには、次の CSS を app.vue
に追加します。
<template>
<NuxtPage />
</template>
<style>
.page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
}
</style>
ページ間を移動すると、次のような結果が得られます。
ページに異なるトランジションを設定するには、ページの definePageMeta
に pageTransition
キーを設定します。
definePageMeta({
pageTransition: {
name: 'rotate'
}
})
アバウトページに移動すると、3D 回転効果が追加されます。
レイアウトトランジション
すべてのレイアウトに自動トランジションを適用するために、レイアウトトランジションを有効にすることができます。
export default defineNuxtConfig({
app: {
layoutTransition: { name: 'layout', mode: 'out-in' }
}
})
ページとレイアウト間にトランジションを追加し始めるには、次の CSS を app.vue
に追加します。
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<style>
.layout-enter-active,
.layout-leave-active {
transition: all 0.4s;
}
.layout-enter-from,
.layout-leave-to {
filter: grayscale(1);
}
</style>
ページ間を移動すると、次のような結果が得られます。
pageTransition
と同様に、definePageMeta
を使用してページコンポーネントにカスタム layoutTransition
を適用できます。
definePageMeta({
layout: 'orange',
layoutTransition: {
name: 'slide-in'
}
})
グローバル設定
これらのデフォルトのトランジション名は、nuxt.config
を使用してグローバルにカスタマイズできます。
pageTransition
と layoutTransition
の両方のキーは、カスタム CSS トランジションの name
、mode
、およびその他の有効なトランジションプロップを渡すことができる JSON シリアライズ可能な値として TransitionProps
を受け入れます。
export default defineNuxtConfig({
app: {
pageTransition: {
name: 'fade',
mode: 'out-in' // デフォルト
},
layoutTransition: {
name: 'slide',
mode: 'out-in' // デフォルト
}
}
})
name
プロパティを変更する場合、CSS クラス名もそれに応じて変更する必要があります。
グローバルトランジションプロパティを上書きするには、definePageMeta
を使用して単一の Nuxt ページのページまたはレイアウトトランジションを定義し、nuxt.config
ファイルでグローバルに定義されているページまたはレイアウトトランジションを上書きします。
definePageMeta({
pageTransition: {
name: 'bounce',
mode: 'out-in' // デフォルト
}
})
トランジションの無効化
pageTransition
と layoutTransition
は特定のルートに対して無効にすることができます。
definePageMeta({
pageTransition: false,
layoutTransition: false
})
または、nuxt.config
でグローバルに無効にします。
export default defineNuxtConfig({
app: {
pageTransition: false,
layoutTransition: false
}
})
JavaScript フック
高度なユースケースでは、JavaScript フックを使用して Nuxt ページのために非常に動的でカスタムなトランジションを作成できます。
この方法は、GSAP などの JavaScript アニメーションライブラリに最適なユースケースを提供します。
definePageMeta({
pageTransition: {
name: 'custom-flip',
mode: 'out-in',
onBeforeEnter: (el) => {
console.log('Before enter...')
},
onEnter: (el, done) => {},
onAfterEnter: (el) => {}
}
})
Transition
コンポーネントで利用可能な追加の JavaScript フック について詳しく学びましょう。
動的トランジション
条件付きロジックを使用して動的トランジションを適用するには、インライン ミドルウェア を活用して、to.meta.pageTransition
に異なるトランジション名を割り当てることができます。
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'slide-right',
mode: 'out-in'
},
middleware (to, from) {
if (to.meta.pageTransition && typeof to.meta.pageTransition !== 'boolean')
to.meta.pageTransition.name = +to.params.id! > +from.params.id! ? 'slide-left' : 'slide-right'
}
})
</script>
<template>
<h1>#{{ $route.params.id }}</h1>
</template>
<style>
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 0.2s;
}
.slide-left-enter-from {
opacity: 0;
transform: translate(50px, 0);
}
.slide-left-leave-to {
opacity: 0;
transform: translate(-50px, 0);
}
.slide-right-enter-from {
opacity: 0;
transform: translate(-50px, 0);
}
.slide-right-leave-to {
opacity: 0;
transform: translate(50px, 0);
}
</style>
ページは次の ID に移動するときに slide-left
トランジションを適用し、前の ID には slide-right
を適用します。
NuxtPage でのトランジション
app.vue
で <NuxtPage />
を使用する場合、transition
プロップを使用してトランジションをグローバルに設定できます。
<template>
<div>
<NuxtLayout>
<NuxtPage :transition="{
name: 'bounce',
mode: 'out-in'
}" />
</NuxtLayout>
</div>
</template>
このページトランジションは、個々のページで definePageMeta
を使用して上書きすることはできません。
View Transitions API(実験的)
Nuxt は View Transitions API の実験的な実装を提供しています(MDN を参照)。これは、異なるページ上の無関係な要素間でトランジションを行う能力を持つ、ネイティブブラウザトランジションを実装するための新しい方法です。
https://nuxt-view-transitions.surge.sh でデモを確認でき、StackBlitz のソースもあります。
Nuxt の統合は活発に開発中ですが、設定ファイルで experimental.viewTransition
オプションを有効にすることで使用できます。
export default defineNuxtConfig({
experimental: {
viewTransition: true
}
})
可能な値は false
、true
、または 'always'
です。
true
に設定すると、ユーザーのブラウザが prefers-reduced-motion: reduce
に一致する場合、Nuxt はトランジションを適用しません(推奨)。always
に設定すると、Nuxt は常にトランジションを適用し、ユーザーの好みを尊重するのはあなた次第です。
デフォルトでは、ビューのトランジションはすべてのページで有効ですが、異なるグローバルデフォルトを設定することもできます。
export default defineNuxtConfig({
app: {
// ビューのトランジションをグローバルに無効にし、ページごとにオプトイン
viewTransition: false
},
})
ページの definePageMeta
に viewTransition
キーを設定することで、ページのデフォルトの viewTransition
値を上書きすることができます。
definePageMeta({
viewTransition: false
})
ページごとにビューのトランジションを上書きするには、experimental.viewTransition
オプションを有効にしている場合にのみ効果があります。
Vue トランジション(pageTransition
や layoutTransition
)を使用して新しい View Transitions API と同じ結果を達成している場合、ユーザーのブラウザが新しいネイティブ Web API をサポートしている場合は Vue トランジションを無効にすることをお勧めします。これを行うには、次の内容で ~/middleware/disable-vue-transitions.global.ts
を作成します。
export default defineNuxtRouteMiddleware(to => {
if (import.meta.server || !document.startViewTransition) { return }
// 組み込みの Vue トランジションを無効にする
to.meta.pageTransition = false
to.meta.layoutTransition = false
})
既知の問題
- ページのセットアップ関数内でデータフェッチを行う場合、現時点ではこの機能の使用を再考することをお勧めします。(設計上、View Transitions は実行中に DOM の更新を完全に凍結します。)View Transition を
<Suspense>
が解決する直前の最終段階に制限することを検討していますが、現時点ではこの機能を採用するかどうかを慎重に検討することをお勧めします。
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/4.x/getting-started/transitions