<NuxtPage>
<NuxtPage> コンポーネントは、pages/ ディレクトリにあるページを表示するために必要です。
<NuxtPage> は Nuxt に組み込まれているコンポーネントで、pages/ ディレクトリにあるトップレベルまたはネストされたページを表示できます。
<NuxtPage> は Vue Router の <RouterView> のラッパーです。内部状態を追加で管理するため、<RouterView> の代わりに使用する必要があります。そうしないと、useRoute() が不正なパスを返す可能性があります。
<NuxtPage> は以下のコンポーネントを含みます:
<template>
<RouterView #default="{ Component }">
<!-- トランジションを使用する場合はオプション -->
<Transition>
<!-- keep-alive を使用する場合はオプション -->
<KeepAlive>
<Suspense>
<component :is="Component" />
</Suspense>
</KeepAlive>
</Transition>
</RouterView>
</template>
デフォルトでは、Nuxt は <Transition> と <KeepAlive> を有効にしません。これらは nuxt.config ファイルで有効にするか、<NuxtPage> の transition と keepalive プロパティを設定することで有効にできます。特定のページを定義したい場合は、ページコンポーネント内の definePageMeta で設定できます。
ページコンポーネントで <Transition> を有効にする場合、ページに単一のルート要素があることを確認してください。
<NuxtPage> は内部で <Suspense> を使用しているため、ページ変更時のコンポーネントライフサイクルの動作は通常の Vue アプリケーションとは異なります。
通常の Vue アプリケーションでは、新しいページコンポーネントは前のものが完全にアンマウントされた後にのみマウントされます。しかし、Nuxt では、Vue の <Suspense> の実装方法により、新しいページコンポーネントは前のものがアンマウントされる前にマウントされます。
Props
name:<RouterView>に一致するルートレコードのコンポーネントオプションで対応する名前のコンポーネントをレンダリングするように指示します。- type:
string
- type:
route: すべてのコンポーネントが解決されたルートの場所。- type:
RouteLocationNormalized
- type:
pageKey:NuxtPageコンポーネントが再レンダリングされるタイミングを制御します。- type:
stringまたはfunction
- type:
transition:NuxtPageコンポーネントでレンダリングされるすべてのページに対するグローバルトランジションを定義します。- type:
booleanまたはTransitionProps
- type:
keepalive:NuxtPageコンポーネントでレンダリングされるページの状態保存を制御します。- type:
booleanまたはKeepAliveProps
- type:
Nuxt は /pages ディレクトリ内のすべての Vue コンポーネントファイルをスキャンしてレンダリングすることで、name と route を自動的に解決します。
Example
例えば、変更されないキーを渡すと、<NuxtPage> コンポーネントは最初にマウントされたときにのみレンダリングされます。
<template>
<NuxtPage page-key="static" />
</template>
現在のルートに基づいた動的なキーを使用することもできます:
<NuxtPage :page-key="route => route.fullPath" />
ここで $route オブジェクトを使用しないでください。<NuxtPage> が <Suspense> でページをレンダリングする方法に問題を引き起こす可能性があります。
また、pageKey は /pages ディレクトリ内の Vue コンポーネントの <script> セクションから definePageMeta を介して key 値として渡すこともできます。
definePageMeta({
key: route => route.fullPath
})Page's Ref
ページコンポーネントの ref を取得するには、ref.value.pageRef を通じてアクセスします。
<script setup lang="ts">
const page = ref()
function logFoo () {
page.value.pageRef.foo()
}
</script>
<template>
<NuxtPage ref="page" />
</template>
const foo = () => {
console.log('foo method called')
}
defineExpose({
foo,
})Custom Props
<NuxtPage> は、階層の下位に渡す必要があるカスタムプロップも受け入れます。
例えば、以下の例では、foobar の値が NuxtPage コンポーネントに渡され、ページコンポーネントに渡されます。
<template>
<NuxtPage :foobar="123" />
</template>
ページコンポーネントで foobar プロップにアクセスできます:
<script setup lang="ts">
const props = defineProps<{ foobar: number }>()
console.log(props.foobar) // 出力: 123
defineProps でプロップを定義していない場合でも、NuxtPage に渡されたプロップはページの attrs から直接アクセスできます:
const attrs = useAttrs()
console.log(attrs.foobar) // 出力: 123tips
このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。
NuxtPage コンポーネントの実務的な活用と注意点
Nuxt.js でページを表示する際に欠かせないのが NuxtPage コンポーネントです。これは pages/ ディレクトリに配置された Vue コンポーネントを動的にレンダリングし、ルーティングに応じたページ表示を実現します。
本記事では、NuxtPage の基本的な仕組みを踏まえつつ、実務での具体的な使い方や注意すべきポイントを詳しく解説します。特に、状態の保持やトランジション、パフォーマンス面での工夫に焦点を当て、NuxtPage をより効果的に活用するための知識を提供します。
まず結論:NuxtPage の要点まとめ
- NuxtPage は Vue Router の RouterView をラップし、Nuxt 独自のページ表示ロジックを提供するコンポーネント
- ページのトランジションや状態保持(keep-alive)を設定可能で、ユーザー体験の向上に役立つ
- ページコンポーネントのライフサイクルは Vue の通常の挙動と異なり、Suspense による非同期レンダリングが行われる
pageKeyプロパティでページの再レンダリングタイミングを制御できるため、動的なキー設定が重要- カスタムプロップを NuxtPage に渡すことで、ページコンポーネントに柔軟にデータを受け渡せる
いつ使うべきか、使わない方がよいケース
使うべきケース
-
動的ルーティングに基づくページ表示
NuxtPage はルーティングに応じて適切なページコンポーネントを自動的に切り替えるため、複雑なページ遷移があるアプリケーションで必須です。 -
ページごとのトランジション効果を実装したい場合
トランジションを有効にすることで、ページ切り替え時のアニメーションを簡単に追加可能です。 -
ページの状態を保持したい場合
keep-alive を使うことで、ページの状態を保存し、戻った際に再レンダリングを防げます。 -
非同期コンポーネントの読み込みをスムーズにしたい場合
Suspense を内包しているため、非同期処理中のローディング表示などを自然に扱えます。
使わない方がよいケース
-
単一ページアプリケーション(SPA)でページ遷移がない場合
ページ切り替えが発生しないなら、NuxtPage の恩恵は少なく、単純なコンポーネント表示で十分です。 -
細かいルーティング制御を自前で行いたい場合
NuxtPage は Nuxt のルーティングシステムに密接に結びついているため、独自のルーティングロジックを使う場合は適さないことがあります。
実務でよくあるユースケースとサンプルコード
1. ページごとに異なるトランジションを設定する
NuxtPage の transition プロパティを使い、ページごとに切り替わるアニメーションを設定できます。
<template>
<NuxtPage :transition="{ name: 'fade', mode: 'out-in' }" />
</template>
ページコンポーネント側で definePageMeta を使い、個別にトランジションを指定することも可能です。
<script setup lang="ts">
definePageMeta({
transition: 'slide-left'
})
</script>
2. ページの状態を保持してユーザーの戻る操作を高速化
keepalive を有効にすると、ページコンポーネントの状態がキャッシュされ、戻ったときに再レンダリングを防げます。
<template>
<NuxtPage :keepalive="true" />
</template>
これにより、フォーム入力やスクロール位置などの状態を維持できます。
3. 動的な pageKey でページの再レンダリングを制御
URL のクエリやパスに応じてページを再レンダリングしたい場合、pageKey に関数を渡します。
<template>
<NuxtPage :page-key="route => route.fullPath" />
</template>
これにより、URL が変わるたびに新しいページコンポーネントがマウントされます。
よくある落とし穴・注意点
1. Suspense によるページのマウントタイミングの違い
NuxtPage は内部で Vue の Suspense を使っているため、新しいページコンポーネントは前のページがアンマウントされる前にマウントされます。
この挙動は通常の Vue Router の RouterView とは異なるため、ライフサイクルフックのタイミングに依存する処理は注意が必要です。
2. トランジション使用時のルート要素の制約
ページコンポーネントでトランジションを有効にする場合、必ず単一のルート要素を持つようにしてください。
複数ルート要素があるとトランジションが正しく動作しません。
3. pageKey に $route を直接使わない
pageKey の関数内で $route を参照すると、Suspense の挙動と干渉して不具合が起きることがあります。
必ず引数の route オブジェクトを使いましょう。
4. keep-alive の過剰使用によるメモリ消費
状態保持は便利ですが、keep-alive を多用するとメモリ使用量が増加し、パフォーマンスに悪影響を及ぼす可能性があります。
必要なページだけに限定して使うことを推奨します。
まとめ
NuxtPage コンポーネントは Nuxt のページ表示の中核を担い、ルーティングに基づく動的なページ切り替えを簡単に実現します。
トランジションや状態保持などの機能を活用することで、ユーザー体験を向上させることが可能です。
一方で、Suspense によるライフサイクルの違いや keep-alive の使い方には注意が必要です。
本記事のポイントを押さえ、NuxtPage を適切に使いこなして、より良い Nuxt アプリケーション開発に役立ててください。
NuxtPage に渡すカスタムプロップはページコンポーネントで defineProps または useAttrs を使って受け取れます。これを活用すると、共通のデータや設定を柔軟にページ間で共有できます。
※このページは Nuxt.js 公式ドキュメントの翻訳ページです。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/api/components/nuxt-page