おはようございます。そうすけです。
運営者:そうすけ
愛媛出身の30代のブロガー兼ソフトウェアエンジニア。
主にフロント・バックの開発を行っています。
趣味はガジェットと植物。
ポートフォリオサイトでパンくずリストを作成してみました。
参考書籍:https://news.nextpublishing.jp/news/detail/1282/
かなり良かったので皆さん読んでみて。
いままで作ったことがなかったので、面白いやり方を参考書で見つけたので記事にまとめます。
パンくずリストとは
パンくずリスト(Breadcrumb)は、ウェブページ上で現在のページがどの階層に位置しているかを示すためのナビゲーション要素です。
階層構造を持つウェブサイトやアプリケーションで使われ、ユーザーにページの位置や経路をわかりやすく表示します。
ホーム > カテゴリ1 > サブカテゴリ1 > 現在のページ
よくサイト上部に、階層が表示されてリンクが作られているものです。
今回は階層ごとのリンクの取得方法について解説します。
Nuxtでの作り方
const urlList = [
"/",
...useRoute()
.path // 現在のルートのパスを取得
.split("/") // パスを "/" で分割し、配列に変換
.filter(path => path !== "") // 空のパスをフィルタリング
.map((_path, index, array) => {
// パスを連結して新しい URL を生成
const url = "/" + array.slice(0, index + 1).join("/");
return url;
}),
];
現在のパスを取得
…useRoute().path で現在のルートのパスを取得します。
この「…」というのがややこしく、スプレッド演算子といって配列を展開して新たな配列を作るときに使用する演算です。
例を挙げると下記のようなイメージです。
ここでのコードは、urlList という新しい配列を作成して、先頭に “/” を追加し、それに useRoute() の返り値を追加しています。
const routeArray = useRoute(); // 仮に ["/home", "/about", "/contact"] とする
const urlList = ["/", ...routeArray];
console.log(urlList);
// 出力: ["/", "/home", "/about", "/contact"]
ようは「/」を先頭にいれたいので、合わせているだけです。
split関数でパスを分割
split(“/”) でパスを / で分割し、それを配列に変換します。
split関数は戻り値が配列になります。
例えば、/home/about/contact が [“”, “home”, “about”, “contact”] に変換されます。
この時、先頭の空文字ができることに注意してください。
filter関数で空白を削除
.filter(path => path !== “”) で空のパスをフィルタリングします。
引数には無名関数として、filterに処理させたいコールバック関数を書きます。
ちなみに()もreturnも省略されています。
これにより、例えば /home/about//contact のような場合に余分な空文字が取り除かれます。
アロー関数の省略記法がわからないかたはこちらを参考。
map関数でそれぞれに「/」をつける
.map((_path, index, array) => {…}) で配列を走査して新しい URL を生成します。
map関数は配列からすべての要素を取りだし、要素それぞれに処理をした後、新たな配列を作る関数です。
参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map
.map((_path, index, array) => {
// _path: 現在処理中の要素(ここでは使っていないので _ で省略)
// index: 現在処理中の要素のインデックス
// array: 元の配列
// array.slice(0, index + 1): 配列の最初から現在の要素までを切り出す
// .join("/"): 切り出した部分を "/" で結合して新しいパスを生成
const url = "/" + array.slice(0, index + 1).join("/");
// 生成した新しいパスを配列に追加
return url;
});
各ステップでの部分的なパスを連結して、その時点での URL を生成しています。
例えば、[“”, “home”, “about”, “contact”] の場合、[ “/home”, “/home/about”, “/home/about/contact”] という URL リストが生成されます。
array.slice(0, 0 + 1).join("/")
:["home"]
→"/home"
array.slice(0, 1 + 1).join("/")
:["home", "about"]
→"/home/about"
array.slice(0, 2 + 1).join("/")
:["home", "about", "contact"]
→"/home/about/contact"
最終的に、urlList には [“/”, “/home”, “/home/about”, “/home/about/contact”] などが格納されます。これにより、現在のルートに基づいて階層的な URL リストが作成されます。
実装コード
<template>
<span class="inline-flex items-center gap-4"></span>
<span v-for="(url,index) in urlList">
<NuxtLink v-if="index < urlList.length-1"
:href="url"
:key="url"
class="inline-block rounded-full h-7 w-7 bg-accent-400 shadow-lg dark:bg-accent-200 hover:opacity-20"
></NuxtLink>
<span v-else
key="current"
class="inline-block rounded-full h-7 w-7 bg-accent-700 shadow-lg dark:bg-accent-50 hover:opacity-20"
>
</span>
</span>
</template>
<script setup lang="ts">
const urlList = [
"/",
//スプレッド演算子で「/」の後ろに演算した配列を展開
...useRoute().path.split("/")
//filter関数の引数に省略形のアロー関数をいれて空白を除去
.filter(path => path !== "")
//配列を切り出して/をつけて加工する
.map((_path,index,array) => {
const url = "/" + array.slice(0,index + 1).join("/");
return url;
}),
];
</script>
トップページは一つです。トップページ以外でURLリストのもの以外を水色の丸で表現しています。
別ページにいくと表示されます。
ダークモードにも対応させています。
コメント