こんにちは。よっしーです(^^)
今日は、ルーティングについて解説しています。
背景
ルーティングについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
+layout
SvelteKitでは、これまでページを完全に独立したコンポーネントとして扱ってきました。ナビゲーション時には、既存の+page.svelteコンポーネントが破棄され、新しいものがその場所に置かれます。
しかし、多くのアプリでは、トップレベルのナビゲーションやフッターなど、すべてのページに表示されるべき要素があります。これらを毎回+page.svelteに繰り返し記述する代わりに、レイアウトに配置することができます。
+layout.svelte
すべてのページに適用されるレイアウトを作成するには、src/routes/+layout.svelte というファイルを作成します。デフォルトのレイアウト (独自のものを持っていない場合に SvelteKit が使用するレイアウト) は次のようになります…
<slot></slot>
…しかし、必要なマークアップ、スタイル、動作を追加できます。唯一の要件は、コンポーネントにページ コンテンツの <slot> が含まれていることです。たとえば、ナビゲーション バーを追加してみましょう。
// src/routes/+layout.svelte
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
<slot></slot>
/、/about、/settings のページを作成すると…
// src/routes/+page.svelte
<h1>Home</h1>
// src/routes/about/+page.svelte
<h1>About</h1>
src/routes/settings/+page.svelte
<h1>Settings</h1>
…ナビは常に表示され、3つのページ間をクリックしても<h1>が置き換わるだけです。
レイアウトは入れ子にできる 例えば、/settingsページが1つだけあるのではなく、/settings/profileや/settings/notificationsのようにサブメニューが共有されているページが入れ子になっているとします(実際の例はgithub.com/settingsを参照してください)。
settings以下のページにのみ適用されるレイアウトを作ることができます(トップレベルのナビゲーションを持つルートレイアウトは継承します):
// src/routes/settings/+layout.svelte
<script>
/** @type {import('./$types').LayoutData} */
export let data;
</script>
<h1>Settings</h1>
<div class="submenu">
{#each data.sections as section}
<a href="/settings/{section.slug}">{section.title}</a>
{/each}
</div>
<slot></slot>
次のセクションの +layout.js の例を見ると、データがどのように入力されるかを確認できます。 デフォルトでは、各レイアウトはその上のレイアウトを継承します。それが望ましくない場合もあります。この場合、高度なレイアウトが役に立ちます。
+layout.js
+page.svelte が +page.js からデータをロードするのと同じように、+layout.svelte コンポーネントは +layout.js のロード関数からデータを取得できます。
// src/routes/settings/+layout.js
/** @type {import('./$types').LayoutLoad} */
export function load() {
return {
sections: [
{ slug: 'profile', title: 'Profile' },
{ slug: 'notifications', title: 'Notifications' }
]
};
}
+layout.js がページ オプション (prerender、ssr、csr) をエクスポートする場合、それらは子ページのデフォルトとして使用されます。 レイアウトのロード関数から返されたデータは、そのすべての子ページでも利用できます。
// src/routes/settings/profile/+page.svelte
<script>
/** @type {import('./$types').PageData} */
export let data;
console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script>
多くの場合、ページ間を移動するときにレイアウト データは変更されません。 SvelteKit は、必要に応じてロード関数をインテリジェントに再実行します。
+layout.server.js
サーバー上でレイアウトのロード関数を実行するには、レイアウトを +layout.server.js に移動し、LayoutLoad タイプを LayoutServerLoad に変更します。 +layout.js と同様に、+layout.server.js はページ オプション (プリレンダリング、ssr、csr) をエクスポートできます。
おわりに
今日は、 ルーティングについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント