nuxt logo

ドキュメント翻訳(非公式)

トランジション

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 キーを設定します。

definePageMeta({
  pageTransition: {
    name: 'rotate'
  }
})

アバウトページに移動すると、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
definePageMeta({
  layout: 'orange',
  layoutTransition: {
    name: 'slide-in'
  }
})

グローバル設定

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

pageTransitionlayoutTransition の両方のキーは、カスタム CSS トランジションの namemode、およびその他の有効なトランジションプロップを渡すことができる JSON シリアライズ可能な値として TransitionProps を受け入れます。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: {
      name: 'fade',
      mode: 'out-in' // デフォルト
    },
    layoutTransition: {
      name: 'slide',
      mode: 'out-in' // デフォルト
    }
  }
})

name プロパティを変更する場合、CSS クラス名もそれに応じて変更する必要があります。

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

pages/some-page.vue
definePageMeta({
  pageTransition: {
    name: 'bounce',
    mode: 'out-in' // デフォルト
  }
})

トランジションの無効化

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

pages/some-page.vue
definePageMeta({
  pageTransition: false,
  layoutTransition: false
})

または、nuxt.config でグローバルに無効にします。

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

JavaScript フック

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

この方法は、GSAP などの JavaScript アニメーションライブラリに最適なユースケースを提供します。

pages/some-page.vue
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 プロップを使用してトランジションをグローバルに設定できます。

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 を参照)。これは、異なるページ上の無関係な要素間でトランジションを行う能力を持つ、ネイティブブラウザトランジションを実装するための新しい方法です。

https://nuxt-view-transitions.surge.sh でデモを確認でき、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: {
    // ビューのトランジションをグローバルに無効にし、ページごとにオプトイン
    viewTransition: false
  },
})

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

pages/about.vue
definePageMeta({
  viewTransition: false
})

ページごとにビューのトランジションを上書きするには、experimental.viewTransition オプションを有効にしている場合にのみ効果があります。

Vue トランジション(pageTransitionlayoutTransition)を使用して新しい 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> が解決する直前の最終段階に制限することを検討していますが、現時点ではこの機能を採用するかどうかを慎重に検討することをお勧めします。