路由系统
介绍
Svelte 官方文档中并没有讲怎么使用路由,但是通过 npm cerate svelte@latest 创建 Svelte 项目的时候,官方会使用 SvelteKit作为项目的路由系统
SvelteKit
可以看这个 https://kit.svelte.dev/docs/introduction 官方文档进行了解,或者也可以听我讲两句有个大概的了解,再去看文档也不迟
基本规则 +page.svelte
SvelteKit 的路由是基于文件系统的,在通过上面的命令生成的项目中,有一个最主要的文件夹--src/routes,你所有要展示的页面都是在这个文件夹下面的
举个最简单的例子:http://localhost:8080/blogs/112233,在这种 url 下面,我们并不关心前面的 host 和 port,而是关心后面的 path 部分--/blogs/112233
在整个路由系统中,只有特定的几个文件是会被识别,然后展示或执行的,他们都是以 + 开头,
对于这样的 path,在项目中的具体显示就是 src/routes/blogs/[id] 的文件结构,在 routes,blogs,[id],这几个文件夹下面都有个 +page.svelte 文件
| path | 显示页面文件 |
|---|---|
| / | /routes/+page.svelte |
| /blogs | /routes/blogs/+page.svelte |
| /blogs/[id] | /routes/blogs/[id]/+page.svelte |
<div>
<p>root page works!</p>
</div>
<style>
div {
background-color: #ccc;
}
</style>
<div>
<p>blogs page works!</p>
</div>
<style>
div {
background-color: #aaa;
}
</style>
<div>
<p>blogs [id] works!</p>
</div>
<style>
div {
background-color: #999;
}
</style>
+layout.svelte
在上面的页面中,每个+page.svelte 对应每个路由的页面,但是在 path / 下面的一些内容需要带到 /blogs 下面中,例如整个页面的 header、导航栏、头像、登录登出等
这就需要 +layout.svelte,在和 +page.svelte 同级的地方,都可以创建一个 +layout.svelte 文件
路由系统如果检查到有 +layout.svelte ,就会优先渲染 +layout.svelte 的页面
需要注意的一点就是,如果你没有在 +layout.svelte 中加入 <slot /> 的话,那么和这个路由同级的 +page.svelte 以及子路由的 +page.svelte,+layout.svelte 就都不会进行渲染
如果加入 <slot /> 的话,那么和这个路由同级的 +page.svelte 以及子路由的 +page.svelte,+layout.svelte 就会渲染在这个插槽中
routes
│ +layout.svelte
│ +page.svelte
│
└─blogs
│ +layout.svelte
│ +page.svelte
│
└─[id]
+page.svelte
<div>
<p>root layout works!</p>
<ul>
<li><a href="/">/(root)</a></li>
<li><a href="/blogs">/blogs</a></li>
<li><a href="/blogs/112233">/blogs/112233</a></li>
</ul>
<slot />
</div>
<style>
div {
background-color: #ddd;
}
</style>
<div>
<p>blogs layout works!</p>
<slot />
</div>
<style>
div {
background-color: #bbb;
}
</style>
+page.js
当路由跳转到当前 +page.svelte 页面的时候,就会在页面加载前加载 +page.js,通常用来监听路由的变化,获取路由信息,然后给页面 return 初始化数据
+page.js return 的数据,+page.svelte 可以通过 export let data; 来获取
在这个例子中,url(/blogs/112233)中的 id 信息:112233,就可以通过 params 获取到,然后传递给 page.svelte 页面中使用
routes
│ +layout.svelte
│ +page.js
│ +page.svelte
│
└─blogs
│ +layout.svelte
│ +page.js
│ +page.svelte
│
└─[id]
+page.js
+page.svelte
export async function load({ fetch, params }) {
return {
rootPageJs: "this is root page.js",
};
}
<script>
export let data;
</script>
<div>
<p>root page works!</p>
<p>from root page.js data: {data.rootPageJs}</p>
</div>
<style>
div {
background-color: #ccc;
}
</style>
export async function load({ fetch, params }) {
return {
blogsPageJs: "this is blogs page.js",
};
}
<script>
export let data;
</script>
<div>
<p>blogs page works!</p>
<p>from blogs page.js data: {data.blogsPageJs}</p>
</div>
<style>
div {
background-color: #aaa;
}
</style>
export async function load({ fetch, params }) {
return params;
}
<script>
export let data;
</script>
<div>
<p>blogs {data.id} works!</p>
<p>from blogs [id] page.js data id: {data.id}</p>
</div>
<style>
div {
background-color: #999;
}
</style>
+layout.js
和 +page.js 类似,当路由跳转到当前 +layout.svelte 页面的时候,就会在页面加载前加载 +layout.js
+layout.js return 的数据,+layout.svelte 可以通过 export let data; 来获取
+layout.js return 的数据,也可以在子路由的 +page.svelte 的 export let data;中获取
routes
│ +layout.js
│ +layout.svelte
│ +page.js
│ +page.svelte
│
└─blogs
│ +layout.js
│ +layout.svelte
│ +page.js
│ +page.svelte
│
└─[id]
+page.js
+page.svelte
export function load() {
return {
rootLayoutJs: "this is root layout.js",
};
}
<script>
export let data;
</script>
<div>
<p>root layout works!</p>
<ul>
<li><a href="/">/(root)</a></li>
<li><a href="/blogs">/blogs</a></li>
<li><a href="/blogs/112233">/blogs/112233</a></li>
</ul>
<p>from root layout.js data: {data.rootLayoutJs}</p>
<slot />
</div>
<style>
div {
background-color: #ddd;
}
</style>
<script>
export let data;
</script>
<div>
<p>root page works!</p>
<p>from root layout.js data: {data.rootLayoutJs}</p>
<p>from root page.js data: {data.rootPageJs}</p>
</div>
<style>
div {
background-color: #ccc;
}
</style>
export function load() {
return {
blogsLayoutJs: 'this is blogs layout.js'
};
}
<script>
export let data;
</script>
<div>
<p>blogs layout works!</p>
<p>from root layout.js data: {data.rootLayoutJs}</p>
<p>from blogs layout.js data: {data.blogsLayoutJs}</p>
<slot />
</div>
<style>
div {
background-color: #bbb;
}
</style>
<script>
export let data;
</script>
<div>
<p>blogs page works!</p>
<p>from root layout.js data: {data.rootLayoutJs}</p>
<p>from blogs layout.js data: {data.blogsLayoutJs}</p>
<p>from blogs page.js data: {data.blogsPageJs}</p>
</div>
<style>
div {
background-color: #aaa;
}
</style>
<script>
export let data;
</script>
<div>
<p>blogs {data.id} works!</p>
<p>from root layout.js data: {data.rootLayoutJs}</p>
<p>from blogs layout.js data: {data.blogsLayoutJs}</p>
<p>from blogs [id] page.js data id: {data.id}</p>
</div>
<style>
div {
background-color: #999;
}
</style>
注意
+page.js 和 +layout.js 相当于 Angular 的路由守卫,可以进行路由的拦截
但是要注意的是,在其中进行接口调用的时候,需要在前面加上 export const ssr = false;
否则会出现首屏加载出错
+server.js
+server.js 可以让你设计一套 restful api 以便在开发的时候进行调用
它返回的并不是 +page.svelte 这类的页面组件,而是 post,delete,put 等对应 http method 的方法