🔗
Nuxt.js: NuxtLink, aタグ の使いどき
基本
<NuxtLink>
Nuxt.js でWebサイトを作成する際に、同じサイト内の別ページへのリンクには <NuxtLink>
コンポーネントを使用する。
<template>
<NuxtLink to="/about">About Page</NuxtLink>
</template>
<a>
Twitter、YouTubeなど、別サイトへのリンクには、通常通り <a>
タグをそのまま使用する。
<template>
<a href="https://twitter.com/amotarao">My Twitter</a>
</template>
同じドメインでの特殊な管理状況での使い分け
同じドメインでのページでも、一部のみまたは複数の特設ページで Nuxt.js のプロジェクトを使い分けている場合、別サイトの扱いと同様になる。
例:
https://example.com/
|- index.html <- Nuxt.js プロジェクトA
|- about/index.html <- Nuxt.js プロジェクトA
|
|- special/ <- Nuxt.js プロジェクトB
|- index.html <- Nuxt.js プロジェクトB
|- form/index.html <- Nuxt.js プロジェクトB
|
|- super/ <- Nuxt.js プロジェクトC
|- index.html <- Nuxt.js プロジェクトC
|- star/index.html <- Nuxt.js プロジェクトC
同じプロジェクト内のリンクは NuxtLink
、プロジェクトを跨ぐページのリンクは <a>
と使い分ける。
また、nuxt.config.js
の router.base
を設定するはずで、ページにはそれぞれに合わせた <base>
タグが挿入されている。
下記を参考に実装の上、リンク先が想定と正しい動作をしているかをよく確認すること。
<!-- プロジェクトC で プロジェクトA内 /about へのリンクを追加 -->
<template>
<div>
<!-- NG: /special/super/about を表示しようとする (VueRouter によって) -->
<NuxtLink to="/about">About</a>
<!-- NG: /special/super/about に遷移する (<base> によって) -->
<a href="/about">About</a>
<!-- NG: /special/super/https://example.com/about を表示しようとする (VueRouter によって) -->
<NuxtLink to="https://example.com/about">About</a>
<!-- OK -->
<a href="https://example.com/about">About</a>
</div>
</template>
<NuxtLink>
, <a>
を出し分けする
リンクにスタイルなどを付与したコンポーネントを作ることはよくあることである。
タグ名(コンポーネント名)を入れ替えるために <component is="">
が利用できる。
props で指定
タグ名をそのまま <component>
の is
に入るようにする。
<tempate>
<component
:is="tag"
class="link"
:href="tag === 'a' ? url : undefined"
:to="tag !== 'a' ? url : undefined"
>
<slot />
</component>
</tempate>
<script>
export default {
props: {
url: {
type: String,
required: true,
},
tag: {
type: String,
default: 'a',
validator: (tag) => ['a', 'NuxtLink'].includes(tag),
},
},
};
</script>
computed で判定
URL が外部のものかを判定し、自動でタグを切り替えるようにする。
例は url
が http://
または https://
の場合に外部リンクと判定するものである。
<tempate>
<component
:is="isExternal ? 'a' : 'NuxtLink'"
class="link"
:href="isExternal ? url : undefined"
:to="!isExternal ? url : undefined"
>
<slot />
</component>
</tempate>
<script>
export default {
props: {
url: {
type: String,
required: true,
},
},
computed: {
isExternal() {
return this.url.match(/^https?:\/\//);
},
},
};
</script>
Discussion
なぜ undefined ?