今天來繼續介紹 SvelteKit 的路由。
+layout.svlete
主要是來建立頁面之間共用的佈局,像是如果我有一個 header 長這樣:
<nav>
<a href="/">Home</a>
<a href="/day16">day16</a>
<a href="/day17">day17</a>
</nav>
在 SvelteKit 中一般情況下,可以直接使用
<a href='' />
來作為 redirect 的 component ,不用像其他框架使用<Link />
之類的特別 component。
當然不會想要每一個 +page.svelte
都手動加上這些東西,那這時我們只要放在 src/routes/+layout.svelte
就可以讓 src/routes/**
之後的所有 +page.svelte
都可以擁有一樣的佈局
<!-- in src/routes/+layout.svelte-->
<nav>
<a href="/">Home</a>
<a href="/day16">day16</a>
<a href="/day17">day17</a>
</nav>
<slot/>
這個 <slot />
是 Svelte 4 讓我們可以把 component 傳進一個 component裡的方式,就跟我們在 Day 10 中使用 {#snippet}
加上 {@render children}
,總之在這個例子中 +page.svelte
的東西會被丟到 <slot/>
的位置。
其實在
+layout.svelte
也可以使用$props
取的children
,但這裡還是先按照 SvelteKit 官方文件的使用方式,畢竟 Svelte 5 還是在 preview 階段。
新增一下src/routes/day17/+page.svelte
<h1>Day17</h1>
之後就可以來看一下我們現在畫面:
會發現不管到哪個頁面都可以顯示出我們的 header 。
那如果我新增一個 src/routes/day17/+layout.svelte
呢?
<nav>
<a href="/">Home</a>
<a href="/day16">day16</a>
</nav>
<slot />
所以如果我有一群 nested 的 +layout.svelte
,在預設情況下他們會堆疊起來。也就是說src/routes/+layout.svelte
是影響到 src/routes/**/+page.svelte
那src/routes/day17/+layout.svelte
就是會影響到 src/routes/day17/**/+page.svelte
以這個例子來說,如果有個 day17/foo/+page.svelte
他也會同時出現兩個 nav
<h1>src/routes/day17/foo/+page.svelte</h1>
跟 +page.ts
一樣我們也可以在這裡使用 load
function ,讓同一個 scope 的頁面都可以獲得一樣的資料,而且跟 +layout.svelte
的邏輯類似的是 Svelte
會自動幫我們把這些 data
給 merge 在一起,而且當然也可以使用 params
。
// in src/routes/+layout.ts
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = () => {
return {
title: 'Hello world! ',
content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
};
// in src/routes/day17/+layout.ts
import type { LayoutLoad } from './$types';
export const load: LayoutLoad = ({ params }) => {
return {
name: params?.name || 'foo',
title: '[Day 17] Hello world! '
};
};
<!-- in src/routes/day17/[name]/+page.svelte -->
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
interface Props {
data: PageData;
}
let { data }: Props = $props();
console.log('data', $page.params, data);
</script>
<h1>{$page.params.name}</h1>
會發現 title
被覆蓋成 src/routes/day17/+layout.ts
的內容了,且 name
也可以正確被加上去。
就跟在 +page.ts
一樣,我們可以在 +layout.ts
去設定 ssr
以及 csr
等等的參數,那他的影響範圍的邏輯就跟其他 +layout 的道理是一樣的。
https://github.com/toddLiao469469/30days-for-svelte5/tree/main/src/routes/day17