SvelteKitでぱんくずを実装する時のアイデア
概要
SvelteKitでのぱんくずの実装のアイデアです。
何をしたいか
ざっくり
親階層のぱんくずのデータはそのまま使用して、子階層でその親ページの内容を再度書かなくていいようにする
というのをやります。
子孫ページで親ページのタイトルとかパスをいちいちまた書くのはめんどくさいですよね。
あんなめんどくさいこといちいちやってられません。
例
親ページ>子ページ>孫ページ>ひ孫ページ
という階層があるサイトがありました。ひ孫ページではそれまでのすべての親ページの情報をぱんくずに表示する必要があります。
めんどくさいですね…
これをSvelteとSvelteKitがデフォルトで持っている機能を使っていい感じに実装したいなと思いました。
デモ
触ったことある人はデモを見ればわかると思うのでみてください。
https://www.sveltelab.dev/her1i0ohl5wajzy
ポイントを説明
SvelteKitには+layout.server.js
などでload
関数からreturnしたデータを+page.svelte
などで使用できる仕様があります。(Next.jsでいうとgetServerSidePropsみたいなやつ)
このload
関数ですが、前の階層のload
関数でreturnした内容をparent()
で取得することができる便利な機能があります。
これめっちゃ便利です。
デモサイトでは親階層の/projects/+layout.server.js
で
export const load = async ({ params }) => {
const breadcrumb = [
{ name: 'プロジェクト一覧', path: '/projects' }
]
return { breadcrumb }
}
しています。
その下の階層の/projects/[id]/+layout.server.js
では
export const load = async ({ params, parent }) => {
const { id } = params
const { breadcrumb } = await parent() // Point!!
const lastPath = breadcrumb[breadcrumb.length - 1].path
return {
project: {
id,
title: `プロジェクト${id}詳細`
},
breadcrumb: [
...breadcrumb,
{
name: '記事詳細',
path: `${lastPath}/${id}`
}
]
}
}
のように書いていますが、load
関数のなかでconst { breadcrumb } = await parent()
しているところがポイントです。
ここで取得されるbreadcrumb
はparent()
関数名から予想がつくと思いますが、一つ前の階層のload
関数でreturnしておいたbreadcrumb
から取得されます。
これを下の階層に向けてどんどんやっていけば、カレントの階層ではそのページの情報を書くだけでよくなります。
最高ですね〜
というわけでここまでくればぱんくずに渡したいデータは用意できているので、/projects/[id]/edit/+page.svelte
などで
import { breadcrumbStore } from '$lib/Breadcrumb'
export let data
$: ({breadcrumb, project} = data)
$: breadcrumbStore.set(breadcrumb)
するだけです。
これでめんどくさいぱんくずの表示がちょっと楽になるのではないでしょうか。
他にいい実装方法があったら教えてください〜!
感想
- Svelteはstoreがデフォルトの機能にあるので他のライブラリを探したりする必要がなくて楽
-
parent()
の使い勝手がかなりいい(親ページで使ったデータを子ページで使いたいことが多い) - 簡単
- SvelteLab最高〜〜〜
SvelteKitはいいぞ。
Discussion