Nuxt で提供されるコンポーネント
Nuxt はいくつかの重要なコンポーネントをいっしょに提供しており、アプリケーションを構築する際に役立ちます。これらのコンポーネントはグローバルで利用可能になっており、それらを使うにあたってインポートする必要ないことを意味します。
以降では、組み込まれているコンポーネントそれぞれについて説明します。
Nuxt コンポーネント
<Nuxt>
コンポーネントはページコンポーネントで表示するために使います。基本的にこのコンポーネントは、表示されているページに応じて、ページコンポーネントの中にあるものに置き換えられます。それゆえ、<Nuxt>
コンポーネントをレイアウトに追加することは重要です。
<template>
<div>
<div>My nav bar</div>
<Nuxt />
<div>My footer</div>
</div>
</template>
<Nuxt>
コンポーネントはレイアウト 内部でのみ使うことができます。<Nuxt>
コンポーネントは nuxt-child-key
のプロパティを取得できます。このプロパティは <RouterView>
に渡されるため、トランジションは動的なページ内で正しく動作するようになります。
<RouterView>
の内部の key
プロパティで処理されるためには 2 つの方法があります。
-
<Nuxt>
コンポーネントでnuxtChildKey
プロパティを使う
<template>
<div>
<Nuxt :nuxt-child-key="someKey" />
</div>
</template>
-
ページ コンポーネントで
key
オプションをstring
またはfunction
として追加する
export default {
key(route) {
return route.fullPath
}
}
NuxtChild コンポーネント
このコンポーネントは、ネストされたルートで子コンポーネントを表示するために使われます。
例:
-| pages/
---| parent/
------| child.vue
---| parent.vue
このファイルツリーは以下のルートが生成されます:
;[
{
path: '/parent',
component: '~/pages/parent.vue',
name: 'parent',
children: [
{
path: 'child',
component: '~/pages/parent/child.vue',
name: 'parent-child'
}
]
}
]
child.vue
コンポーネントを表示するために、pages/parent.vue
内部で <NuxtChild>
コンポーネントを挿入する必要があります:
<template>
<div>
<h1>I am the parent view</h1>
<NuxtChild :foobar="123" />
</div>
</template>
keep-alive
<Nuxt>
コンポーネント、そして <NuxtChild>
コンポーネント両方は、keep-alive
そして keep-alive-props
を受け付けます。
<template>
<div>
<Nuxt keep-alive :keep-alive-props="{ exclude: ['modal'] }" />
</div>
</template>
<!-- 以下のようなものに変換されます -->
<div>
<KeepAlive :exclude="['modal']">
<RouterView />
</KeepAlive>
</div>
<template>
<div>
<NuxtChild keep-alive :keep-alive-props="{ exclude: ['modal'] }" />
</div>
</template>
<!-- 以下のようなものに変換されます -->
<div>
<KeepAlive :exclude="['modal']">
<RouterView />
</KeepAlive>
</div>
<NuxtChild>
コンポーネントはまた通常の Vue コンポーネントのようなプロパティも受け付けます。
<template>
<div>
<NuxtChild :key="$route.params.id" />
</div>
</template>
例を確認するには、nested-routes の例 を参照してください。
NuxtLink コンポーネント
アプリケーションのページ間を遷移するためには、 <NuxtLink>
コンポーネントを使用する必要があります。このコンポーネントは、 Nuxt に含まれているため、他のコンポーネントといっしょにインポートする必要はありません。HTML の <a>
タグに似ていますが、href="/about"
を使う代わりに、to="/about"
を使うことができます。以前に vue-router
を使用したことがある場合は、<RouterLink>
の代わりに <NuxtLink>
を使用することができます。
pages
フォルダの index.vue
ページにリンクするシンプルな例です:
<template>
<NuxtLink to="/">Home page</NuxtLink>
</template>
<NuxtLink>
コンポーネントは全ての内部リンクに対して使う必要があります。つまり、サイト内のページへ全てのリンクに対して <NuxtLink>
を使用する必要があります。<a>
タグは全ての外部リンクに対して使用する必要があります。つまり、他のウェブサイトにリンクがある場合は、それらに対して <a>
タグを使用する必要があります。
<template>
<div>
<h1>Home page</h1>
<NuxtLink to="/about"
>About (internal link that belongs to the Nuxt App)</NuxtLink
>
<a href="https://v2.nuxt.com">External Link to another page</a>
</div>
</template>
<RouterLink>
についてもっと知りたい場合は、Vue Router のドキュメント を読んで参考にしてください。<NuxtLink>
にはスマートプリフェッチング もサポートしています。prefetchLinks
Nuxt は自動的にスマートプリフェッチングをサポートしています。つまり、ビューポートまたはスクロール時にリンクが表示されたことを検知し、そしてユーザーがリンクをクリックしたときにすぐに使えるよう、ページにおいて JavaScript をプリフェッチします。Nuxt はブラウザがビジー状態でないときにのみリソースをロードし、接続がオフラインの場合や 2g の接続しかできない場合はプリフェッチをスキップします。
特定のページに対するプリフェッチングの無効
しかし、一部のリンクでプリフェッチを無効にしたい場合があります。ページに多くの JavaScript が存在する、または プリフェッチ されるページが多数ある場合、ロードする必要のあるサードパーティスクリプトが多数ある場合などです。特定のリンクのプリフェッチを無効にするには、no-prefetch
プロパティを使用できます。Nuxt v2.10.0 以降では、prefetch
プロパティを false
に設定して使用することもできます。
<NuxtLink to="/about" no-prefetch>About page not pre-fetched</NuxtLink>
<NuxtLink to="/about" :prefetch="false">About page not pre-fetched</NuxtLink>
グローバルなプリフェッチングの無効
全てのリンクでプリフェッチングを無効にするために、prefetchLinks
に false
を設定します:
export default {
router: {
prefetchLinks: false
}
}
Nuxt v2.10.0 からは、prefetchLinks
に false
を設定していても、特定のリンクをプリフェッチしたい場合は、prefetch
プロパティを使用できます:
<NuxtLink to="/about" prefetch>About page pre-fetched</NuxtLink>
linkActiveClass
linkActiveClass
はアクティブなリンクにおいて vue-router
の class と同じように動作します。どのリンクがアクティブなのかを表示したい場合は、nuxt-link-active
という class の CSS を作成するとよいでしょう。
.nuxt-link-active {
color: red;
}
必要であれば、class 名を別のものに設定することもできます。これを行うには、nuxt.config.js
ファイルの router プロパティで linkActiveClass
を変更することができます。
export default {
router: {
linkActiveClass: 'my-custom-active-link'
}
}
linkExactActiveClass
linkExactActiveClass
は、vue-router
の class と同じように、完全にアクティブなリンクに対して動作します。どのリンクが完全に一致してアクティブになっているかを表示したい場合は、nuxt-link-exact-active
という class の CSS を作成するだけです。
.nuxt-link-exact-active {
color: green;
}
必要であれば、class 名を別のものに設定することもできます。これを行うには、nuxt.config.js
ファイルの router プロパティで linkExactActiveClass
を変更することができます。
export default {
router: {
linkExactActiveClass: 'my-custom-exact-active-link'
}
}
linkPrefetchedClass
linkPrefetchedClass を使うと、プリフェッチされたすべてのリンクにスタイルを追加することができます。これは、デフォルトの動作を変更した後、どのリンクがプリフェッチされているかをテストするのに最適です。linkPrefetchedClass は、デフォルトでは無効になっています。これを有効にするには、nuxt-config.js
ファイルの router プロパティに追加する必要があります。
export default {
router: {
linkPrefetchedClass: 'nuxt-link-prefetched'
}
}
そして、そのクラスに対してスタイルを追加することができます
.nuxt-link-prefetched {
color: orangeRed;
}
nuxt-link-prefetched
class を使いますが、好きな名前を付けることができます。client-only コンポーネント
このコンポーネントは、コンポーネントを意図的にクライアントサイドでのみレンダリングするために使用します。クライアント側でのみコンポーネントをインポートするには、クライアントサイド専用のプラグインにコンポーネントを登録します。
<template>
<div>
<sidebar />
<client-only placeholder="Loading...">
<!-- このコンポーネントはクライアント側のみレンダリングされます -->
<comments />
</client-only>
</div>
</template>
クライアント側で <client-only />
がマウントされるまで、スロットをプレースホルダーとして使用します。
<template>
<div>
<sidebar />
<client-only>
<!-- このコンポーネントはクライアント側のみレンダリングされます -->
<comments />
<!-- ローディングインジケータはサーバー側でレンダリングされます -->
<template #placeholder>
<comments-placeholder />
</template>
</client-only>
</div>
</template>
<client-only>
内の $refs
が $nextTick
を使用しても準備できないことがありますが、その場合は $nextTick
を何度か呼び出す必要があります:mounted(){
this.initClientOnlyComp()
},
methods: {
initClientOnlyComp(count = 10) {
this.$nextTick(() => {
if (this.$refs.myComp) {
//...
} else if (count > 0) {
this.initClientOnlyComp(count - 1);
}
});
},
}
<client-only>
の代わりに <no-ssr>
を使います。











































