Skip to main content

路由系统

介绍​

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
/routes/+page.svelte
<div>
<p>root page works!</p>
</div>

<style>
div {
background-color: #ccc;
}
</style>
/routes/blogs/+page.svelte
<div>
<p>blogs page works!</p>
</div>

<style>
div {
background-color: #aaa;
}
</style>
/routes/blogs/[id]/+page.svelte
<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
/routes/+layout.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>
/routes/blogs/+layout.svelte
<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
/routes/+page.js
export async function load({ fetch, params }) {
return {
rootPageJs: "this is root page.js",
};
}
/routes/+page.svelte
<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>
/routes/blogs/+page.js
export async function load({ fetch, params }) {
return {
blogsPageJs: "this is blogs page.js",
};
}
/routes/blogs/+page.svelte
<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>
/routes/blogs/[id]/+page.js
export async function load({ fetch, params }) {
return params;
}
/routes/blogs/[id]/+page.svelte
<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; 来获取

tip

+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
/routes/+layout.js
export function load() {
return {
rootLayoutJs: "this is root layout.js",
};
}
/routes/+layout.svelte
<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>
/routes/+page.svelte
<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>
/routes/+layout.js
export function load() {
return {
blogsLayoutJs: 'this is blogs layout.js'
};
}
/routes/blogs/+layout.svelte
<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>
/routes/blogs/+page.svelte
<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>
/routes/blogs/[id]/+page.svelte
<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>

注意​

tip

+page.js 和 +layout.js 相当于 Angular 的路由守卫,可以进行路由的拦截

但是要注意的是,在其中进行接口调用的时候,需要在前面加上 export const ssr = false;

否则会出现首屏加载出错

+server.js​

+server.js 可以让你设计一套 restful api 以便在开发的时候进行调用

它返回的并不是 +page.svelte 这类的页面组件,而是 post,delete,put 等对应 http method 的方法