SvelteKit:一个基于Svelte开发服务端渲染网站的框架
SvelteKit
是一个用于构建各种规模的Web
应用程序的框架且具有出色的开发体验和基于文件系统的灵活路由。
与单页应用程序不同,SvelteKit
不会在SEO
,渐进增强或初始加载体验上做出让步-但与传统的服务器呈现的应用程序不同,导航是即时的,类似于应用程序的感觉。(摘自SvelteKit官网)
入门
npm init svelte@next my-app
cd my-app
npm install
npm run dev
SvelteKit
是基于Svelte
构建的一个服务端渲染框架,对标的是React
的Next
框架,最初是基于Snowpack
打包的,后来Vite
出来之后,团队将其迁移到了Vite
。此框架有三大特点:
- 基于
Svelte
- 友好的服务端渲染,
SEO
,渐进式增强,以及SPA
的流畅导航。 - 使用基于文件系统的路由,代码拆分,离线支持。
总之如果你想尝试Svelte
技术栈的话,此框架是开发的不二选择。你现在的所看到的网站就是用SvelteKit
开发的静态网站。
router(路由)
SvelteKit
是基于文件系统的生成的路由,默认在src/routes
的.svelte
文件都是一个页面,路由就是文件名且区分大小写。如:routes/about.svelte
→/about
、routes/userHome.svelte
→/userHome
。所以建议使用短横线
命名法命名文件,即:user-home
。
嵌套路由
实现嵌套路由就只需嵌套目录即可,目录下的index.svelte
会自动将当前目录名转换为路由。如:routes/news/index.svelte
→/news
、routes/news/list.svelte
→/news/list
。
动态路由
如果需要使用动态路由可以使用[路由名].svelte
来命名文件,如:routes/news/[id].svelte
→/news/:id
。其动态的路由可作为params
参数传入页面中,获取方法会在下面说明。
如果需要多个动态参数传入的话,可使用-
分割。如:routes/news/[category]-[id].svelte
→/news/:idcategory/:id
。
如果路由的动态数量未知,可以使用剩余参数,即:routes/[tree]/[dir]/[...file]
→/:tree/:dir/...file
。如:routes/master/docs/router/01.md
解析为master
→tree
、dir
→docs
、file
→router/01.md
layout(布局)
如果需要使用布局模板的话,可以在其目录下创建__layout.svelte
,则此目录下的所有页面都会应用此布局。布局页中必须含有<slot></slot>
,其代表页面内容在布局页的位置。如果在routes
下创建一个__layout.svelte
则所有页面都会应用此布局,如果想重置布局,则在其目录下创建一个__layout.reset.svelte
文件即可,然后此目录下的所有页面都会应用此布局,而不会布局中含有布局。如果需要嵌套布局则在目录下继续创建一个__layout.svelte
即可。
error(错误页面)
如果想自定义页面错误页的话,可以在目录下创建一个__error.svelte
,默认就近查找,如果没有就一直往上一级目录查找,知道routes
目录下,如果都没有,则使用默认的错误页,建议在routes
下创建一个__error.svelte
。
错误页面有一个load
函数,其接受一个对象:{error,status}
<script context="module">
export function load({ error, status }) {
return {
props: {
title: `${status}: ${error.message}`
}
};
}
</script>
<script>
export let title;
</script>
<h1>{title}</h1>
load 函数
每个页面、布局、错误页都有一个组件创建前运行的函数:load
,此函数在服务端渲染和客户端中运行,并允许获取页面数据。此函数要在script context="module
标签中。
load 函数的接收和输出的参数类型为:
// 输入
type LoadInput = {
page: {
host: string;
path: string;
params: Record<string, string>;
query: URLSearchParams;
};
fetch: (info: RequestInfo, init?: RequestInit) => Promise<Response>;
session: any;
context: Record<string, any>;
};
// 输出
type LoadOutput = {
status?: number;
error?: string | Error;
redirect?: string;
props?: Record<string, any>;
context?: Record<string, any>;
maxage?: number;
};
<script context="module">
export function load({
page: {
params: { id }
}
}) {
return {
props: {
title: '详情',
id
}
};
}
</script>
<script>
export let title;
export let id;
</script>
<h1>{title}</h1><div>当前详情ID:{id}</div>
- 在
load
函数里面应该使用fetch
方法获取数据,以避免重复的网络请求- 不应该使用
window
、document
灯任何浏览器对象
服务端渲染数据请求
SvelteKit
允许你为每一个页面提供了一个同名的以.json.js
为后缀的文件,此文件中可以导出一个异步的函数,一般在此文件中获取数据并返回,通过load
函数加载数据。.json.js
文件支持三个异步函数:get
、post
、del
。异步函数的接收和输出参数类型:
type Headers = Record<string, string>;
type Request<Locals = Record<string, any>, Body = unknown> = {
method: string;
host: string;
headers: Headers;
path: string;
params: Record<string, string>;
query: URLSearchParams;
rawBody: string | Uint8Array;
body: ParameterizedBody<Body>;
locals: Locals; // populated by hooks handle
};
type EndpointOutput = {
status?: number;
headers?: Headers;
body?: string | Uint8Array | JSONValue;
};
type RequestHandler<Locals = Record<string, any>> = (
request: Request<Locals>
) => void | EndpointOutput | Promise<EndpointOutput>;
news/[id].svelte
<script context="module">
export const load = async ({
page: {
params: { id }
},
fetch
}) => {
const res = await fetch(`${id}.json`);
if (res.ok) {
const data = await res.json();
return {
props: {
details: data
}
};
}
const { message } = await res.json();
return {
error: new Error(message)
};
};
</script>
<script>
export let details;
</script>
<h1>{details.title}</h1><div>{details.description}</div>
news/[id].json.js
import { fetchDetails } from 'api';
export const get: RequestHandler<string> = async ({ params: { id } }) => {
const data = fetchDetails(id);
return {
body: data
};
};
以上就是基本的SvelteKit
介绍,更多的详细介绍请前往官网查看。