SvelteKit 是新一代应用框架的代表。它当然会为您搭建应用,包含 Next 一直以来提供的基于文件的路由、部署和服务器端渲染。但 SvelteKit 还支持嵌套布局、同步页面数据的服务器端变异以及其他一些我们即将介绍的特性。 本文旨在对 SvelteKit 做一个高级概述,希望能激发从未使用过 SvelteKit 的任何人的兴趣。这将是一次轻松的旅程。如果您喜欢看到的内容,完整的文档在这里。 从某些方面来说,写这篇文章很有挑战性。SvelteKit 是一个应用框架 为此,我们将构建一个久经考验的待办事项应用程序作为示例。但别担心,这将更多地关注 SvelteKit 的工作原理,而不是创建另一个待办事项应用程序。 本文中所有代码都可以在 GitHub 上找到。此项目也已部署在 Vercel 上,可进行实时演示。 启动新的 SvelteKit 项目非常简单。在终端中运行 创建项目
npm create svelte@latest your-app-name<https:> 并回答问题提示。请务必选择“Skeleton Project”,但对于 TypeScript、ESLint 等,您可以根据需要进行任何选择。<https:>
<p>项目创建完成后,运行 <code>npm i<https:> 和 <code>npm run dev<https:>,开发服务器应该开始运行。在浏览器中启动 <code>localhost:5173<https:>,您将获得骨架应用程序的占位符页面。<https:>
<h3>基本路由<https:>
<p>请注意 <code>src<https:> 下的 <code>routes<https:> 文件夹。它包含我们所有路由的代码。其中已经有一个 <code> page.svelte<https:> 文件,其中包含根 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712<https:> 路由的内容。无论您在文件层次结构中的哪个位置,该路径的实际页面始终名为 <code> page.svelte<https:>。考虑到这一点,让我们为 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list<https:>、<code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712details<https:>、<code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712adminhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712user-settings<https:> 和 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712adminhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712paid-status<https:> 创建页面,并为每个页面添加一些文本占位符。<https:>
<p>您的文件布局应如下所示:<https:>
<p>您应该能够通过更改浏览器地址栏中的 URL 路径来导航。<https:>
<h3>布局<https:>
<p>我们希望在我们的应用程序中添加导航链接,但我们当然不希望将它们的标记复制到我们创建的每个页面上。因此,让我们在 <code>routes<https:> 文件夹的根目录中创建一个 <code> layout.svelte<https:> 文件,SvelteKit 将将其视为所有页面的全局模板。让我们向其中添加一些内容:<https:>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><nav>
<ul>
<li>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712">Home<https:>
<https:>
<li>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list">To-Do list<https:>
<https:>
<li>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712adminhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712paid-status">Account status<https:>
<https:>
<li>
<a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712adminhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712user-settings">User settings<https:>
<https:>
<https:>
<https:>
<slot><https:>
<style>
nav {
background-color: beige;
}
nav ul {
display: flex;
}
li {
list-style: none;
margin: 15px;
}
a {
text-decoration: none;
color: black;
}
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712style><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>一些基本的导航和一些基本样式。特别重要的是 <code><slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 标签。这<em>不是<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>您与 Web 组件和 Shadow DOM 一起使用的 slot,而是 Svelte 的一个特性,指示放置我们内容的位置。页面渲染时,页面内容将滑入 slot 所在的位置。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>现在我们有一些导航了!我们不会赢得任何设计比赛,但我们也没有尝试这样做。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h3>嵌套布局<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p>如果我们希望所有管理页面继承我们刚刚构建的普通布局,并且还共享所有管理页面(但只有管理页面)的一些共同点,该怎么办?没问题,我们在根 <code>admin<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 目录中添加另一个 <code> layout.svelte<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件,它将被其下方的所有内容继承。让我们这样做并添加此内容:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false"><div>This is an admin page<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712div>
<slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot>
<style>
div {
padding: 15px;
margin: 10px 0;
background-color: red;
color: white;
}
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712style><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>我们添加一个红色横幅,表明这是一个管理页面,然后,像以前一样,一个 <code><slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 表示我们希望页面内容去的地方。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们之前的根布局会渲染。根布局内有一个 <code><slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 标签。嵌套布局的内容进入根布局的 <code><slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>。最后,嵌套布局定义它自己的 <code><slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712slot><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>,页面内容将在其中渲染。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>如果您导航到管理页面,您应该会看到新的红色横幅:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h3>定义数据<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p>好的,让我们渲染一些实际数据——或者至少看看我们如何渲染一些实际数据。创建和连接到数据库的方法有很多。这篇文章是关于 SvelteKit 的,而不是管理 DynamoDB,因此我们将改为“加载”一些静态数据。但是,我们将使用与您用于真实数据相同的机制来读取和更新它。对于真实的 Web 应用程序,请将返回静态数据的函数替换为连接和查询您使用的任何数据库的函数。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>让我们在 <code>libhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712todoData.ts<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中创建一个非常简单的模块,它返回一些静态数据以及人工延迟以模拟实际查询。您将看到这个 <code>lib<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件夹通过 <code>$lib<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 在其他地方导入。这是 SvelteKit 为该特定文件夹提供的功能,您甚至可以添加自己的别名。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">let todos = [
{id:1,标题:“写Sveltekit介绍博客文章”,分配:“ Adam”,标签:[1]},
{id:2,标题:“写Sveltekit高级数据加载博客文章”,分配:“ Adam”,标签:[1]},
{id:3,标题:“准备Renderatl Talk”,分配:“ Adam”,标签:[2]},
{id:4,标题:“修复所有Sveltekit错误”,分配:“ Rich”,标签:[3]},
{id:5,标题:“编辑亚当的博客文章”,分配:“杰夫”,标签:[4]},,
];
令tags = [
{id:1,名称:“ Sveltekit Content”,颜色:“ DED”},
{id:2,名称:“会议”,颜色:“紫色”},,
{id:3,名称:“ Sveltekit开发”,颜色:“ pink”},
{id:4,名称:“ CSS-Tricks Admin”,颜色:“蓝色”},
];
导出start wait = async(量)=&gt;新的Promise((RES)=&GT; settimeout(res,金额?? 100));
导出异步函数getTodos(){
等待等待();
返回todos;
}
导出异步函数getTags(){
等待等待();
返回标签。
查找[tag.id] = tag;
返回查找;
},{});
}
导出异步函数getTodo(id){
返回todos.find((t)=&gt; t.id == id);
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
(<p>“详细信息”页面中使用最后一个函数)。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h3> <<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p> sevelte 页面?方法有很多,但现在> <code> list <https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>文件夹中创建一个> page.server.server.js <code>文件
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>import {getTodos,getTags} “ $ libhttps://www.php.cn/link/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9a9a9a9a9a9f8c8460e5e5e55555555712 ar;
导出功能load(){
const todos = getTodos();
const tags = getTags();
返回 {
毒品,
标签,
};
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<gante> <<pre class="brush:php;toolbar:false"> load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>>,它会提取页面所需的数据。请注意<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>那么,我们如何从页面组件访问这些数据呢?SvelteKit 为我们的组件提供了一个带有数据的 <code>data<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 属性。我们将使用反应式赋值从其中访问我们的待办事项和标签。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们的列表页面组件现在看起来像这样。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false"><script>
export let data;
$: ({ todos, tags } = data);
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712script>
<table>
<thead>
<tr>
<th>Task<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712th>
<th>Tags<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712th>
<th>Assigned<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712th>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712tr>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712thead>
<tbody>
{#each todos as t}
<tr>
<td>{t.title}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712td>
<td>{t.tags.map((id) => tags[id].name).join(', ')}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712td>
<td>{t.assigned}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712td>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712tr>
{https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712each}
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712tbody>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712table>
<style>
th {
text-align: left;
}
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712style><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>这应该会渲染我们的待办事项!<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h3>布局组<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p>在我们继续进行“详细信息”页面和变异数据之前,让我们快速了解一下 SvelteKit 的一个非常巧妙的功能:<strong>布局组<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>。我们已经看到了所有管理页面的嵌套布局,但是如果我们想在文件系统的同一级别上任意页面之间共享布局,该怎么办?特别是,如果我们只想在我们的列表页面和详细信息页面之间共享布局,该怎么办?我们已经在该级别上有一个全局布局。相反,我们可以创建一个新目录,但名称要放在括号中,如下所示:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们现在有一个涵盖列表和详细信息页面的布局组。我将其命名为 <code>(todo-management)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>,但您可以将其命名为任何您喜欢的名称。需要明确的是,此名称<em>不会<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>影响布局组内页面的 URL。URL 将保持不变;布局组允许您向页面添加共享布局,而无需它们都构成 <code>routes<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中整个目录的一部分。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们<em>可以<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712em>添加一个 <code> layout.svelte<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件和一些愚蠢的 <code><div><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 横幅,上面写着“嘿,我们正在管理待办事项”。但是让我们做一些更有趣的事情。布局可以定义 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数,以便为其下的所有路由提供数据。让我们使用此功能来加载我们的标签——因为我们将在详细信息页面中使用我们的标签——以及我们已经拥有的列表页面。实际上,仅仅为了提供单个数据而强制使用布局组几乎肯定是不值得的;最好在每个页面的 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数中复制该数据。但对于这篇文章,它将提供我们需要看到 SvelteKit 新功能的借口!<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>首先,让我们进入列表页面的 <code> page.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件并从中删除标签。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">import { getTodos } from "$libhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712todoData";
export function load() {
const todos = getTodos();
return {
todos,
};
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>我们的列表页面现在应该产生一个错误,因为没有 <code>tags<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 对象。让我们通过在布局组中添加一个 <code> layout.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件来解决此问题,然后定义一个加载标签的 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">import { getTags } from "$libhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712todoData";
export function load() {
const tags = getTags();
return {
tags,
};
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>就这样,我们的列表页面又渲染出来了!<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h4>我们正在从多个位置加载数据<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h4>
<p>让我们重点说明一下这里发生的事情:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<ul>
<li>我们为布局组定义了一个 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数,我们将其放在 <code> layout.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<li>这为布局服务的<strong>所有<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>页面提供数据——在本例中,这意味着我们的列表和详细信息页面。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<li>我们的列表页面还定义了一个 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数,该函数位于其 <code> page.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件中。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<li>SvelteKit 会执行繁重的工作,将这些数据源的结果合并在一起,并在 <code>data<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中提供两者。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul>
<h3>详细信息页面<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p>我们将使用详细信息页面来编辑待办事项。首先,让我们在列表页面中添加一列,该列链接到包含待办事项 ID 的查询字符串的详细信息页面。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false"><td><a href="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712details?id={t.id}">Edit<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712a><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712td><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>现在让我们构建详细信息页面。首先,我们将添加一个加载器来获取我们正在编辑的待办事项。在 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712details<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中创建一个 <code> page.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>,内容如下:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">import { getTodo } from "$libhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712todoData";
export function load({ url }) {
const id = url.searchParams.get("id");
const todo = getTodo(id);
return {
todo,
};
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>我们的加载器带有 <code>url<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 属性,我们可以从中提取查询字符串值。这使得查找我们正在编辑的待办事项变得很容易。让我们渲染该待办事项,以及编辑它的功能。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>SvelteKit 具有出色的内置变异功能,只要您使用表单即可。还记得表单吗?这是我们的详细信息页面。为了简洁起见,我已经省略了样式。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false"><script>
import { enhance } from "$apphttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712forms";
export let data;
$: ({ todo, tags } = data);
$: currentTags = todo.tags.map((id) => tags[id]);
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712script>
<div>
{#each currentTags as tag}
{tag.name}
{https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712each}
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712div>
<form method="POST" action="https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712editTodo" use:enhance>
<input type="hidden" name="id" value={todo.id} https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712>
<input type="text" name="title" bind:value={todo.title} https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712>
<button type="submit">Save<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712button>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712form><https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>我们像以前一样从布局组的加载器中获取标签,从页面的加载器中获取待办事项。我们从待办事项的标签 ID 列表中获取实际的标签对象,然后渲染所有内容。我们创建一个表单,其中包含一个隐藏的 ID 输入和一个真实的标题输入。我们显示标签,然后提供一个按钮来提交表单。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>如果您注意到 <code>use:enhance<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code>,这只是告诉 SvelteKit 使用渐进式增强和 Ajax 来提交我们的表单。您可能总是会使用它。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h4>我们如何保存我们的编辑?<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h4>
<p>注意到表单本身上的 <code>action="?https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712editTodo"<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 属性了吗?这告诉我们我们想要将编辑后的数据提交到哪里。对于我们的情况,我们想提交到一个 <code>editTodo<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> “操作”。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>让我们通过将以下内容添加到我们已经为“详细信息”提供的 <code> page.server.js<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 文件中来创建它(该文件当前具有一个 <code>load()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 函数,用于获取我们的待办事项):<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">import { redirect } from "@sveltejshttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712kit";
import { updateTodo, wait } from "$libhttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712datahttps://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712todoData";
https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712 ...
export const actions = {
async editTodo({ request }) {
const formData = await request.formData();
const id = formData.get("id");
const newTitle = formData.get("title");
await wait(250);
await updateTodo(id, newTitle);
throw redirect(303, "https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list");
},
};<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>表单操作为我们提供了一个 <code>request<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 对象,它提供对我们的 <code>formData<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 的访问,该对象具有用于我们各种表单字段的 <code>get<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 方法。我们添加了隐藏的 ID 值输入,以便我们可以在这里获取它,以便查找我们正在编辑的待办事项。我们模拟延迟,调用新的 <code>updateTodo()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 方法,然后将用户重定向回 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 页面。<code>updateTodo()<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 方法只是更新我们的静态数据;在现实生活中,您会在您使用的任何数据存储中运行某种更新。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<pre class="brush:php;toolbar:false">export async function updateTodo(id, newTitle) {
const todo = todos.find((t) => t.id == id);
Object.assign(todo, { title: newTitle });
}<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712pre>
<p>让我们试试看。我们首先转到列表页面:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>现在,让我们单击其中一个待办事项的“编辑”按钮,以在 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712details<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 中调出编辑页面。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们将添加一个新标题:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>现在,单击“保存”。这应该会将我们带回到 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 页面,并应用新的待办事项标题。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>新的标题是如何出现的?这是自动的。一旦我们重定向到 <code>https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712list<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 页面,SvelteKit 就会像往常一样自动重新运行我们所有的加载器。这是像 SvelteKit、Remix 和 Next 13 这样的新一代应用程序框架提供的关键进步。它们不会为您提供一种方便的渲染页面方法,然后祝您好运获取您可能需要更新数据的任何端点,而是将数据变异与数据加载集成在一起,允许两者协同工作。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>您可能想知道的一些事情……<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p><strong>这种变异更新似乎并不太令人印象深刻。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>加载器会在您导航时重新运行。如果我们没有在表单操作中添加重定向,而是停留在当前页面上,会发生什么?SvelteKit 将像以前一样在表单操作中执行更新,但仍将重新运行当前页面的所有加载器,包括页面布局中的加载器。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p><strong>我们可以有更针对性的方法来使我们的数据无效吗?<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>例如,我们的标签没有被编辑,因此在现实生活中,我们不想重新查询它们。是的,我向您展示的只是 SvelteKit 中的默认表单行为。您可以通过向 <code>use:enhance<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> 提供回调来关闭默认行为。然后 SvelteKit 提供手动失效函数。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p><strong>每次导航时加载数据可能会很昂贵且不必要。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712strong>我可以像使用 react-query 这样的工具一样缓存这些数据吗?是的,只是不同。SvelteKit 允许您设置(然后尊重)Web 已提供的缓存控制标头。我将在后续文章中介绍缓存失效机制。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>我们在整篇文章中使用静态数据并在内存中修改值。如果您需要还原所有内容并重新开始,请停止并重新启动 <code>npm run dev<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712code> Node 进程。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<h3>总结<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712h3>
<p>我们只是触及了 SvelteKit 的表面,但希望您已经看到了足以让您兴奋的东西。我不记得上次我发现 Web 开发如此有趣是什么时候了。有了捆绑、路由、SSR 和部署等开箱即用的功能,我可以花更多时间编码而不是配置。<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<p>以下是一些您可以用作学习 SvelteKit 的后续步骤的更多资源:<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712p>
<ul>
<li>宣布 SvelteKit 1.0(Svelte 博客)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<li>SvelteKit 初学者课程(Vercel)<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<li>SvelteKit 文档<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712li>
<https://www.php.cn/link/29a9f8c8460e5e2be4edde557fd83712ul></style></https:></slot></https:></https:></https:></https:></a>
</li></https:></https:></a>
</li></https:></https:></a>
</li></https:></https:></a>
</li>
</ul></nav></pre><div class="contentsignin">登录后复制</div></div></https:></https:>
以上是Sveltekit入门的详细内容。更多信息请关注PHP中文网其他相关文章!