トランジション

Vue またはネイティブブラウザの View Transitions を使用して、ページとレイアウト間のトランジションを適用します。
Nuxt は Vue の<Transition>コンポーネントを利用して、ページとレイアウト間のトランジションを適用します。

ページトランジション

ページトランジションを有効にすると、すべてのページに自動的なトランジションが適用されます。

nuxt.config.ts
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>

これにより、ページ間を移動すると以下の結果が生成されます。

ページごとに異なるトランジションを設定するには、ページの definePageMetapageTransition キーを設定します。

<script setup lang="ts">
definePageMeta({
  pageTransition: {
    name: 'rotate',
  },
})
</script>

about ページに移動すると、3D 回転効果が追加されます。

レイアウトトランジション

レイアウトトランジションを有効にすると、すべてのレイアウトに自動的なトランジションが適用されます。

nuxt.config.ts
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 をページコンポーネントに適用できます。

pages/about.vue
<script setup lang="ts">
definePageMeta({
  layout: 'orange',
  layoutTransition: {
    name: 'slide-in',
  },
})
</script>

グローバル設定

nuxt.config を使用して、これらのデフォルトのトランジション名をグローバルにカスタマイズできます。

pageTransitionlayoutTransition の両方のキーはTransitionPropsJSON シリアル化可能な値を許容し、カスタム CSS トランジションの namemode、およびその他の有効なトランジションプロパティを渡すことができます。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: {
      name: 'fade',
      mode: 'out-in', // default
    },
    layoutTransition: {
      name: 'slide',
      mode: 'out-in', // default
    },
  },
})
name プロパティを変更した場合は、それに応じて CSS クラスの名前も変更する必要があります。

グローバルなトランジションプロパティを上書きするには、definePageMeta を使用して、個々の Nuxt ページに対してページまたはレイアウトのトランジションを定義し、nuxt.config ファイルでグローバルに定義されているページまたはレイアウトのトランジションを上書きします。

pages/some-page.vue
<script setup lang="ts">
definePageMeta({
  pageTransition: {
    name: 'bounce',
    mode: 'out-in', // default
  },
})
</script>

トランジションの無効化

pageTransitionlayoutTransition は、特定のルートに対して無効にすることができます。

pages/some-page.vue
<script setup lang="ts">
definePageMeta({
  pageTransition: false,
  layoutTransition: false,
})
</script>

または、nuxt.config でグローバルに無効にすることもできます。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: false,
    layoutTransition: false,
  },
})

JavaScript フック

高度なユースケースでは、JavaScript フックを使用して、Nuxt ページ用の非常に動的でカスタムなトランジションを作成できます。

この方法は、次のような JavaScript アニメーションライブラリの完璧なユースケースを提供します。GSAP.

pages/some-page.vue
<script setup lang="ts">
definePageMeta({
  pageTransition: {
    name: 'custom-flip',
    mode: 'out-in',
    onBeforeEnter: (el) => {
      console.log('Before enter...')
    },
    onEnter: (el, done) => {},
    onAfterEnter: (el) => {},
  },
})
</script>
追加のJavaScript フックについて詳しくは、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>

ページは、次の ID に移動するときは slide-left トランジションを適用し、前の ID に移動するときは slide-right を適用するようになりました。

NuxtPage を使用したトランジション

<NuxtPage />app.vue で使用されている場合、トランジションは transition プロパティで設定することで、グローバルにトランジションを有効にできます。

app/app.vue
<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 オプションを有効にすることで可能です。

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    viewTransition: true,
  },
})

設定可能な値は、falsetrue、または 'always' です。

true に設定すると、ユーザーのブラウザが prefers-reduced-motion: reduce と一致する場合、Nuxt はトランジションを適用しません (推奨)。always に設定すると、Nuxt は常にトランジションを適用し、ユーザーの好みを尊重するかどうかはあなた次第です。

デフォルトでは、すべてのページでビュー遷移が有効になっていますが、異なるグローバルデフォルトを設定することも可能です。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    // Disable view transitions globally, and opt-in on a per page basis
    viewTransition: false,
  },
})

ページの definePageMetaviewTransition キーを設定することで、ページのデフォルトの viewTransition 値を上書きすることができます。

pages/about.vue
<script setup lang="ts">
definePageMeta({
  viewTransition: false,
})
</script>
ページごとにビュー遷移を上書きしても、experimental.viewTransition オプションを有効にしている場合にのみ効果があります。

もしあなたが、新しい View Transitions API と同じ結果を得るために pageTransitionlayoutTransition のような 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 を制限することを検討していますが、それまでの間、これが当てはまる場合は、この機能を採用するかどうかを慎重に検討することをお勧めします。