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中文網其他相關文章!