トランジション
<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>
<template>
<div>
<h1>Home page</h1>
<NuxtLink to="/about">About page</NuxtLink>
</div>
</template>
<template>
<div>
<h1>About page</h1>
<NuxtLink to="/">Home page</NuxtLink>
</div>
</template>
これにより、ページ間を移動すると以下の結果が生成されます。
ページごとに異なるトランジションを設定するには、ページの definePageMeta に pageTransition キーを設定します。
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'rotate',
},
})
</script>
<template>
<NuxtPage />
</template>
<style>
/* ... */
.rotate-enter-active,
.rotate-leave-active {
transition: all 0.4s;
}
.rotate-enter-from,
.rotate-leave-to {
opacity: 0;
transform: rotate3d(1, 1, 1, 15deg);
}
</style>
about ページに移動すると、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>
<template>
<div>
<pre>default layout</pre>
<slot />
</div>
</template>
<style scoped>
div {
background-color: lightgreen;
}
</style>
<template>
<div>
<pre>orange layout</pre>
<slot />
</div>
</template>
<style scoped>
div {
background-color: #eebb90;
padding: 20px;
height: 100vh;
}
</style>
<template>
<div>
<h1>Home page</h1>
<NuxtLink to="/about">About page</NuxtLink>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: 'orange',
})
</script>
<template>
<div>
<h1>About page</h1>
<NuxtLink to="/">Home page</NuxtLink>
</div>
</template>
これにより、ページ間を移動すると以下の結果が生成されます。
pageTransition と同様に、definePageMeta を使用してカスタムの layoutTransition をページコンポーネントに適用できます。
<script setup lang="ts">
definePageMeta({
layout: 'orange',
layoutTransition: {
name: 'slide-in',
},
})
</script>
グローバル設定
nuxt.config を使用して、これらのデフォルトのトランジション名をグローバルにカスタマイズできます。
pageTransition と layoutTransition の両方のキーはTransitionPropsJSON シリアル化可能な値を許容し、カスタム CSS トランジションの name、mode、およびその他の有効なトランジションプロパティを渡すことができます。
export default defineNuxtConfig({
app: {
pageTransition: {
name: 'fade',
mode: 'out-in', // default
},
layoutTransition: {
name: 'slide',
mode: 'out-in', // default
},
},
})
name プロパティを変更した場合は、それに応じて CSS クラスの名前も変更する必要があります。グローバルなトランジションプロパティを上書きするには、definePageMeta を使用して、個々の Nuxt ページに対してページまたはレイアウトのトランジションを定義し、nuxt.config ファイルでグローバルに定義されているページまたはレイアウトのトランジションを上書きします。
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'bounce',
mode: 'out-in', // default
},
})
</script>
トランジションの無効化
pageTransition と layoutTransition は、特定のルートに対して無効にすることができます。
<script setup lang="ts">
definePageMeta({
pageTransition: false,
layoutTransition: false,
})
</script>
または、nuxt.config でグローバルに無効にすることもできます。
export default defineNuxtConfig({
app: {
pageTransition: false,
layoutTransition: false,
},
})
JavaScript フック
高度なユースケースでは、JavaScript フックを使用して、Nuxt ページ用の非常に動的でカスタムなトランジションを作成できます。
この方法は、次のような JavaScript アニメーションライブラリの完璧なユースケースを提供します。GSAP.
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: 'custom-flip',
mode: 'out-in',
onBeforeEnter: (el) => {
console.log('Before enter...')
},
onEnter: (el, done) => {},
onAfterEnter: (el) => {},
},
})
</script>
Transition コンポーネントで利用できます。動的なトランジション
条件付きロジックを使用して動的なトランジションを適用するには、インラインの ミドルウェア を利用して、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>
<script setup lang="ts">
const route = useRoute()
const id = computed(() => Number(route.params.id || 1))
const prev = computed(() => '/' + (id.value - 1))
const next = computed(() => '/' + (id.value + 1))
</script>
<template>
<div>
<slot />
<div v-if="$route.params.id">
<NuxtLink :to="prev">⬅️</NuxtLink> |
<NuxtLink :to="next">➡️</NuxtLink>
</div>
</div>
</template>
ページは、次の ID に移動するときは slide-left トランジションを適用し、前の ID に移動するときは slide-right を適用するようになりました。
NuxtPage を使用したトランジション
<NuxtPage /> が app.vue で使用されている場合、トランジションは transition プロパティで設定することで、グローバルにトランジションを有効にできます。
<template>
<div>
<NuxtLayout>
<NuxtPage
:transition="{
name: 'bounce',
mode: 'out-in',
}"
/>
</NuxtLayout>
</div>
</template>
definePageMeta で上書きできないことに注意してください。View Transitions API (実験的)
Nuxt には、View Transitions APIの実験的な実装が搭載されています (詳細はMDNを参照)。これは、異なるページ上の無関係な要素間を遷移する機能 (とりわけ) を持つ、ネイティブブラウザのトランジションを実装するエキサイティングな新しい方法です。
デモをチェックできます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: {
// Disable view transitions globally, and opt-in on a per page basis
viewTransition: false,
},
})
ページの definePageMeta に viewTransition キーを設定することで、ページのデフォルトの viewTransition 値を上書きすることができます。
<script setup lang="ts">
definePageMeta({
viewTransition: false,
})
</script>
experimental.viewTransition オプションを有効にしている場合にのみ効果があります。もしあなたが、新しい View Transitions API と同じ結果を得るために pageTransition や layoutTransition のような Vue トランジション (上記参照) も使用している場合、ユーザーのブラウザが新しいネイティブ Web API をサポートしているならば、Vue トランジションを無効にすることを検討したいかもしれません。これは、次の内容で ~/middleware/disable-vue-transitions.global.ts を作成することで可能です。
export default defineNuxtRouteMiddleware((to) => {
if (import.meta.server || !document.startViewTransition) {
return
}
// Disable built-in Vue transitions
to.meta.pageTransition = false
to.meta.layoutTransition = false
})
既知の問題
- ページ設定関数内でデータフェッチを実行している場合、現時点ではこの機能の使用を再検討することをお勧めします。(View Transitions は、実行中に DOM の更新を完全にフリーズするように設計されています。) 私たちは、
<Suspense>が解決する直前の瞬間に View Transition を制限することを検討していますが、それまでの間、これが当てはまる場合は、この機能を採用するかどうかを慎重に検討することをお勧めします。