1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【ひとりカレンダー】フロントエンド開発成長日記Advent Calendar 2022

Day 9

SvelteKitでパンくずリストを実装した話

Last updated at Posted at 2022-12-09

はじめに

SvelteKitを用いてWebアプリケーションを実装した際、
UIコンポーネントとしてFlowbite-svelteを使いました。

image.png

Svelte$app/storesモジュールを使って実装したのでその時のメモ。

前提

  • SvelteKitのアプリケーションが動くこと。
  • Flowbite-svelteを導入していること。

↑に関しては前の記事で解説しています。

実装

Breadcrumb.svelte

<script lang="ts">
  import { Breadcrumb, BreadcrumbItem } from 'flowbite-svelte';
  import { page }  from '$app/stores';
  import { pathname } from './pathname';

  interface Paths {
    route: string;
    name: string;
  }

  $: paths = createBreadcrumb($page.url.pathname);
  
  const createBreadcrumb = (routes) => {
    let swap_paths: Array<Paths> = [];
      routes.split('/').forEach((route) => {
      swap_paths.push({route: route, name: pathname[route]})
    })

    return swap_paths = Array.from(new Map(swap_paths.map(o => [o.route, o])).values());
  }

</script>

<Breadcrumb>
  {#each paths as { route, name }, index}
    {#if paths.length == 1 }
      <BreadcrumbItem home>{name}</BreadcrumbItem>
    {:else if index == 0 }
      <BreadcrumbItem href="/" home>{name}</BreadcrumbItem>
    {:else if index == paths.length - 1 }
      <BreadcrumbItem>{name}</BreadcrumbItem>
    {:else}
      <BreadcrumbItem href="/{route}">{name}</BreadcrumbItem>
    {/if}
  {/each}
</Breadcrumb>

pathname.ts

export const pathname = {
  '': 'Home',
  'list': '一覧',
  'new': '新規作成'
}

解説

$app/storesモジュールのpageについて

ソースコードの解説の前に$app/storesモジュールのpageについて解説します。

こちらのモジュールには、ページ情報が保存されています。
よく使うものを抜粋し、解説していきます。

error

エラー時のメッセージが格納されています。
statusと組み合わせてエラーページを自作できそうです。

例) 404の場合

error: { message: 'Not Found' }

params

パスパラメータが格納されています。
記事ごとのページを表示したりするのに使いそうです。

例) /user/[id] ⇒ /user/1 の場合

params: { id: 1 }

status

レスポンスステータスコードが格納されています。
先ほどのerrorと組み合わせてエラーページを作ったり、状態に合わせて表示物を変えたりできそうです。

例) 200や404の場合

// 200
status: 200

// 404 Not Found
status: 404

url

URL情報が載っています

例) http://localhost:8080の場合

image.png

② ソースコード解説

Flowbite-svelteのパンくずリストは、
クリック時の遷移先と、表示テキストが必要でした

  <BreadcrumbItem href="/" home>{name}</BreadcrumbItem>

そのため、遷移先から表示テキストが参照できるようなHashオブジェクトを作成した。
それがpathname.tsです。

// pathname.ts
export const pathname = {
  '': 'Home',
  'list': '一覧',
  'new': '新規作成'
}

pathname['list']
// ⇒ '一覧'

次に、与えられたパスから、
パンくずリストで使う形式の配列を作成するメソッドを作成しました。

const createBreadcrumb = (routes) => {
let swap_paths: Array<Paths> = [];
  routes.split('/').forEach((route) => {
  swap_paths.push({route: route, name: pathname[route]})
})

return swap_paths = Array.from(new Map(swap_paths.map(o => [o.route, o])).values());
}

createBreadcrumb('/list') 
// ⇒ [{route: '', name: 'Home'}, {route: 'list', name: '一覧'}]

そしてそのメソッドを、パスの変化に合わせてパンくずリストの配列に代入しています。

$: paths = createBreadcrumb($page.url.pathname);

あとはFlowbite-svelteのパンくずリストコンポーネントに合わせて、eachで回せばOK
(Homeは家のアイコンが出るように等工夫しています。)

<Breadcrumb>
  {#each paths as { route, name }, index}
    {#if paths.length == 1 }
      <BreadcrumbItem home>{name}</BreadcrumbItem>
    {:else if index == 0 }
      <BreadcrumbItem href="/" home>{name}</BreadcrumbItem>
    {:else if index == paths.length - 1 }
      <BreadcrumbItem>{name}</BreadcrumbItem>
    {:else}
      <BreadcrumbItem href="/{route}">{name}</BreadcrumbItem>
    {/if}
  {/each}
</Breadcrumb>

終わりです👍

breadcrumb.gif

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?