こんにちは。よっしーです(^^)
今日は、SvelteKitでのデータ読み込みについて解説しています。
背景
SvelteKitでのデータ読み込みについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
SvelteKitでのデータ読み込み
+page.svelte コンポーネント (およびそれに含まれる +layout.svelte コンポーネント) をレンダリングする前に、多くの場合、データを取得する必要があります。これは、ロード関数を定義することによって行われます。
レイアウトデータ
+layout.svelte ファイルは、+layout.js または +layout.server.js 経由でデータを読み込むこともできます。
// src/routes/blog/[slug]/+layout.server.js
import * as db from '$lib/server/database';
/** @type {import('./$types').LayoutServerLoad} */
export async function load() {
return {
posts: await db.getPostSummaries()
};
}
// src/routes/blog/[slug]/+layout.svelte
<script>
/** @type {import('./$types').LayoutData} */
export let data;
</script>
<main>
<!-- +page.svelte is rendered in this <slot> -->
<slot />
</main>
<aside>
<h2>More posts</h2>
<ul>
{#each data.posts as post}
<li>
<a href="/blog/{post.slug}">
{post.title}
</a>
</li>
{/each}
</ul>
</aside>
レイアウト読み込み関数から返されたデータは、子の +layout.svelte コンポーネントと +page.svelte コンポーネント、およびそれが「属する」レイアウトで利用できます。
// src/routes/blog/[slug]/+page.svelte
<script>
import { page } from '$app/stores';
/** @type {import('./$types').PageData} */
export let data;
// we can access `data.posts` because it's returned from
// the parent layout `load` function
$: index = data.posts.findIndex(post => post.slug === $page.params.slug);
$: next = data.posts[index - 1];
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
{#if next}
<p>Next post: <a href="/blog/{next.slug}">{next.title}</a></p>
{/if}
複数のロード関数が同じキーを持つデータを返す場合、最後のロード関数が「勝ち」ます。レイアウト ロードが { a: 1, b: 2 } を返し、ページ ロードが { b: 3, c: 4 } を返すと、その結果は次のようになります。 { a: 1、b: 3、c: 4 }。
$page.data
+page.svelte
コンポーネントと、その上位にある各+layout.svelte
コンポーネントは、自身のデータと親コンポーネントからのすべてのデータにアクセスできます。
しかし、時には逆の状況も必要となります。つまり、親のレイアウトがページデータや子レイアウトのデータにアクセスする必要がある場合があります。例えば、ルートレイアウトが+page.js
や+page.server.js
のload
関数から返されるtitle
プロパティにアクセスしたい場合があります。これは$page.data
を使用することで実現できます。
おわりに
今日は、 SvelteKitでのデータ読み込みについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント