SvelteKit є найновішою з того, що я б назвав фреймворками додатків наступного покоління. Звичайно, він створює для вас програму з маршрутизацією на основі файлів, розгортанням і рендерингом на стороні сервера, які Next робив назавжди. Але SvelteKit також підтримує вкладені макети, мутації сервера, які синхронізують дані на вашій сторінці, і деякі інші нюанси, про які ми поговоримо.
Ця публікація призначена для ознайомлення на високому рівні, щоб, сподіваємося, викликати хвилювання у всіх, хто ніколи не користувався SvelteKit. Це буде невимушений тур. Якщо вам подобається те, що ви бачите, повні документи тут.
У певному сенсі це складно писати. SvelteKit є прикладні рамки. Він існує, щоб допомогти вам створювати... ну, програми. Це ускладнює демонстрацію. Неможливо створити цілу програму в публікації блогу. Тож замість цього ми трохи використаємо нашу уяву. Ми створимо скелет програми, матимемо кілька порожніх заповнювачів інтерфейсу користувача та жорстко закодовані статичні дані. Мета полягає не в створенні справжньої програми, а в тому, щоб показати вам, як працюють рухомі частини SvelteKit, щоб ви могли створити власну програму.
З цією метою ми створимо перевірену та справжню програму To-Do як приклад. Але не хвилюйтеся, це буде більше про те, як працює SvelteKit, ніж про створення ще однієї програми To-Do.
Код для всього в цій публікації доступний на GitHub. Цей проект також розгорнуто на Vercel для демонстрації наживо.
Створення вашого проекту
Створити новий проект SvelteKit досить просто. бігти npm create your-app-name
у терміналі та дайте відповідь на запитання. Обов’язково виберіть «Skeleton Project», але в іншому випадку зробіть будь-який вибір для TypeScript, ESLint тощо.
Після створення проекту запустіть його npm i
та npm run dev
і сервер розробників повинен почати працювати. Розлютитися localhost:5173
у веб-переглядачі, і ви отримаєте сторінку-заповнювач для програми-скелета.
Основна маршрутизація
Зверніть увагу на routes
папка під src
. Там міститься код для всіх наших маршрутів. Вже є +page.svelte
файл із вмістом для кореня /
маршрут. Незалежно від того, де в ієрархії файлів ви знаходитесь, фактична сторінка для цього шляху завжди має назву +page.svelte
. Маючи це на увазі, давайте створимо сторінки для /list
, /details
, /admin/user-settings
та admin/paid-status
, а також додайте кілька текстових заповнювачів для кожної сторінки.
Макет вашого файлу має виглядати приблизно так:
Ви повинні мати можливість переміщатися, змінюючи URL-шляхи в адресному рядку браузера.
макети
Нам потрібні навігаційні посилання в нашій програмі, але ми точно не хочемо копіювати розмітку для них на кожній створеній сторінці. Отже, давайте створимо a +layout.svelte
файл у корені нашого routes
папку, яку SvelteKit розглядатиме як глобальний шаблон для всіх сторінок. Давайте додамо до нього трохи вмісту:
<nav> <ul> <li> <a href="/uk/">Home</a> </li> <li> <a href="/uk/list">To-Do list</a> </li> <li> <a href="/uk/admin/paid-status">Account status</a> </li> <li> <a href="/uk/admin/user-settings">User settings</a> </li> </ul>
</nav> <slot /> <style> nav { background-color: beige; } nav ul { display: flex; } li { list-style: none; margin: 15px; } a { text-decoration: none; color: black; }
</style>
Трохи елементарної навігації з деякими базовими стилями. Особливе значення має те <slot />
тег. Це НЕ слот, який ви використовуєте з веб-компонентами та тіньовою DOM, а радше функція Svelte, яка вказує, куди розмістити наш вміст. Під час візуалізації сторінки вміст сторінки ковзатиме туди, де знаходиться слот.
І тепер у нас є навігація! Ми не виграємо жодного конкурсу дизайну, але ми й не намагаємося.
Вкладені макети
Що, якби ми хотіли, щоб усі наші сторінки адміністратора успадкували звичайний макет, який ми щойно створили, але також мали спільні речі для всіх сторінок адміністратора (але лише сторінок адміністратора)? Немає проблем, ми додамо ще один +layout.svelte
файл у нашому корені admin
каталог, який успадкує все, що знаходиться під ним. Давайте зробимо це та додамо цей вміст:
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
Ми додаємо червоний банер, який вказує на те, що це сторінка адміністратора, а потім, як і раніше, a <slot />
вказуючи, куди ми хочемо розмістити вміст нашої сторінки.
Наш кореневий макет із попередніх візуалізацій. Всередині кореневого макету є a <slot />
тег. Вміст вкладеного макета переходить у кореневий макет <slot />
. І, нарешті, вкладений макет визначає свій власний <slot />
, у який відображається вміст сторінки.
Якщо ви перейдете на сторінки адміністратора, ви побачите новий червоний банер:
Визначення наших даних
Гаразд, давайте візуалізуємо деякі фактичні дані — або принаймні подивимось, як ми можемо відобразити деякі фактичні дані. Є сотні способів створити базу даних і підключитися до неї. Але ця публікація стосується SvelteKit, а не керування DynamoDB, тому замість цього ми «завантажимо» деякі статичні дані. Але для їх читання й оновлення ми використовуватимемо ті самі механізми, що й для реальних даних. Для справжньої веб-програми замініть функції, що повертають статичні дані, функціями, які підключаються та надсилають запити до будь-якої бази даних, яку ви використовуєте.
Давайте створимо дуже простий модуль у lib/data/todoData.ts
який повертає деякі статичні дані разом із штучними затримками для імітації реальних запитів. Ви це побачите lib
папку, імпортовану в інше місце через $lib
. Це функція SvelteKit для конкретної папки, і ви навіть можете додати власні псевдоніми.
let todos = [ { id: 1, title: "Write SvelteKit intro blog post", assigned: "Adam", tags: [1] }, { id: 2, title: "Write SvelteKit advanced data loading blog post", assigned: "Adam", tags: [1] }, { id: 3, title: "Prepare RenderATL talk", assigned: "Adam", tags: [2] }, { id: 4, title: "Fix all SvelteKit bugs", assigned: "Rich", tags: [3] }, { id: 5, title: "Edit Adam's blog posts", assigned: "Geoff", tags: [4] },
]; let tags = [ { id: 1, name: "SvelteKit Content", color: "ded" }, { id: 2, name: "Conferences", color: "purple" }, { id: 3, name: "SvelteKit Development", color: "pink" }, { id: 4, name: "CSS-Tricks Admin", color: "blue" },
]; export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 100)); export async function getTodos() { await wait(); return todos;
} export async function getTags() { await wait(); return tags.reduce((lookup, tag) => { lookup[tag.id] = tag; return lookup; }, {});
} export async function getTodo(id) { return todos.find(t => t.id == id);
}
Функція для повернення плоского масиву наших завдань, пошук наших тегів і функція для отримання окремої справи (ми використаємо цю останню на сторінці подробиць).
Завантаження наших даних
Як отримати ці дані на наших сторінках Svelte? Існує кілька способів, але наразі давайте створимо +page.server.js
файл у нашому list
і помістіть у неї цей вміст:
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
Ми визначили a load()
функція, яка отримує дані, необхідні для сторінки. Зверніть увагу, що ми НЕ await
-дзвінки на наш getTodos
та getTags
асинхронні функції. Це створило б каскад завантаження даних, оскільки ми очікуємо, поки надходять наші завдання, перш ніж завантажувати наші теги. Натомість ми повертаємо необроблені обіцянки від load
, а SvelteKit виконує необхідну роботу await
Ними.
Отже, як отримати доступ до цих даних із нашого компонента сторінки? SvelteKit надає a data
проп для нашого компонента з даними про нього. З нього ми отримаємо доступ до своїх завдань і тегів за допомогою a реактивне призначення.
Наш компонент сторінки списку тепер виглядає так.
<script> export let data; $: ({ todo, tags } = data);
</script> <table cellspacing="10" cellpadding="10"> <thead> <tr> <th>Task</th> <th>Tags</th> <th>Assigned</th> </tr> </thead> <tbody> {#each todos as t} <tr> <td>{t.title}</td> <td>{t.tags.map((id) => tags[id].name).join(', ')}</td> <td>{t.assigned}</td> </tr> {/each} </tbody>
</table> <style> th { text-align: left; }
</style>
І це має відображати наші завдання!
Групи макетів
Перш ніж ми перейдемо до сторінки подробиць і змінимо дані, давайте поглянемо на справді чудову функцію SvelteKit: групи макетів. Ми вже бачили вкладені макети для всіх сторінок адміністратора, але що, якби ми хотіли поділитися макетом між довільними сторінками на одному рівні нашої файлової системи? Зокрема, що, якби ми хотіли поділитися макетом лише між сторінкою списку та сторінкою подробиць? У нас уже є глобальний макет на цьому рівні. Замість цього ми можемо створити новий каталог, але з іменем у круглих дужках, наприклад:
Тепер у нас є група макетів, яка охоплює наші сторінки списку та подробиць. Я назвав це (todo-management)
але ти можеш назвати як завгодно. Щоб було зрозуміло, ця назва буде НЕ впливають на URL-адреси сторінок усередині групи макетів. URL-адреси залишаться незмінними; Групи макетів дозволяють додавати спільні макети до сторінок, при цьому всі вони не складатимуть цілого каталогу в routes
.
We може додати а +layout.svelte
файл і якісь дурні <div>
банер із написом «Гей, ми справляємося зі справами». Але давайте зробимо щось цікавіше. Макети можна визначати load()
функції для надання даних для всіх маршрутів під ними. Давайте скористаємося цією функцією для завантаження наших тегів — оскільки ми будемо використовувати наші теги в нашому details
сторінка — крім в list
сторінку ми вже маємо.
Насправді, змушувати групу макетів просто надавати окрему частину даних майже напевно не варто; краще скопіювати ці дані в load()
функцію для кожної сторінки. Але для цієї публікації це дасть нам виправдання, щоб побачити нову функцію SvelteKit!
Спочатку зайдемо в наш list
сторінок +page.server.js
файл і видаліть з нього теги.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
Наша сторінка списку тепер має видавати помилку, оскільки її немає tags
об'єкт. Давайте виправимо це, додавши a +layout.server.js
файл у нашій групі макетів, а потім визначте a load()
функція, яка завантажує наші теги.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
І ось так знову відображається наша сторінка списку!
Ми завантажуємо дані з кількох місць
Давайте розглянемо те, що тут відбувається:
- Ми визначили a
load()
для нашої групи макетів, яку ми додаємо+layout.server.js
. - Це надає дані для всі сторінок, які обслуговує макет — що в даному випадку означає наші сторінки списку та подробиць.
- Наша сторінка списку також визначає a
load()
функція, яка йде в його+page.server.js
файлу. - SvelteKit виконує величезну роботу, збираючи результати з цих джерел даних, об’єднуючи їх разом і роблячи обидва доступними в
data
.
Наша сторінка деталей
Ми використовуватимемо нашу сторінку подробиць, щоб редагувати пункт справ. По-перше, давайте додамо стовпець до таблиці на нашій сторінці "Список", який посилається на сторінку "Деталі" з ідентифікатором елемента справи в рядку запиту.
<td><a href="/uk/details?id={t.id}">Edit</a></td>
Тепер давайте створимо нашу сторінку подробиць. По-перше, ми додамо завантажувач для захоплення елемента справ, який ми редагуємо. Створити +page.server.js
in /details
, з таким змістом:
import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export function load({ url }) { const id = url.searchParams.get("id"); console.log(id); const todo = getTodo(id); return { todo, };
}
Наш навантажувач поставляється з a url
властивість, з якої ми можемо отримати значення рядка запиту. Це полегшує пошук елемента справ, який ми редагуємо. Давайте візуалізуємо це завдання разом із функціями для його редагування.
SvelteKit має чудові вбудовані можливості мутації, якщо ви використовуєте форми. Пам'ятаєте форми? Ось наша сторінка подробиць. Я виключив стилі для стислості.
<script> import { enhance } from "$app/forms"; export let data; $: ({ todo, tags } = data); $: currentTags = todo.tags.map(id => tags[id]);
</script> <form use:enhance method="post" action="?/editTodo"> <input name="id" type="hidden" value="{todo.id}" /> <input name="title" value="{todo.title}" /> <div> {#each currentTags as tag} <span style="{`color:" ${tag.color};`}>{tag.name}</span> {/each} </div> <button>Save</button>
</form>
Ми забираємо теги, як і раніше, із завантажувача нашої групи макетів, а елемент справ із завантажувача нашої сторінки. Ми беремо реальне tag
об’єкти зі списку завдань ідентифікаторів тегів, а потім відобразити все. Створюємо форму з прихованим введенням ID і реальним введенням заголовка. Ми відображаємо теги, а потім надаємо кнопку для надсилання форми.
Якщо ви помітили use:enhance
, який просто повідомляє SvelteKit використовувати прогресивне вдосконалення, а Ajax — надсилати нашу форму. Ви, ймовірно, завжди будете цим користуватися.
Як зберегти наші зміни?
Зверніть увагу на action="?/editTodo"
атрибут на самій формі? Це вказує нам, куди ми хочемо надіслати відредаговані дані. Для нашого випадку ми хочемо підкоритися editTodo
«дія».
Давайте створимо його, додавши наступне до +page.server.js
файл, який ми вже маємо для подробиць (який наразі має load()
функція, щоб захопити наше завдання):
import { redirect } from "@sveltejs/kit"; // ... export const actions = { async editTodo({ request }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); throw redirect(303, "/list"); },
};
Дії форми дають нам a request
об'єкт, який забезпечує доступ до наш formData
, який має a get
для різних полів форми. Ми додали цей прихований вхід для значення ID, щоб ми могли отримати його тут, щоб знайти елемент справ, який ми редагуємо. Моделюємо затримку, викликаємо нову updateTodo()
метод, потім переспрямовує користувача назад до /list
стор. The updateTodo()
метод лише оновлює наші статичні дані; у реальному житті ви запустили б якесь оновлення в будь-якому сховищі даних, яке ви використовуєте.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
Давайте спробуємо. Спочатку ми перейдемо на сторінку списку:
Тепер давайте клацнемо кнопку «Редагувати» для одного із завдань, щоб відкрити сторінку редагування /details
.
Ми збираємося додати нову назву:
Тепер натисніть «Зберегти». Це повинно повернути нас до нашого /list
із застосованою новою назвою справ.
Як така нова назва з’явилася? Це було автоматично. Одного разу ми перенаправили на /list
сторінку, SvelteKit автоматично повторно запустив усі наші завантажувачі так само, як це було б незалежно від цього. Це ключовий прогрес, завдяки якому фреймворки програм наступного покоління, такі як SvelteKit, Ремікс та Наступний 13 забезпечити. Замість того, щоб надавати вам зручний спосіб візуалізації сторінок, а потім бажати вам удачі в отриманні будь-яких кінцевих точок, які вам можуть знадобитися для оновлення даних, вони інтегрують зміни даних разом із завантаженням даних, дозволяючи двом працювати в тандемі.
Кілька речей, які вам можуть бути цікаві…
Це оновлення мутації не здається надто вражаючим. Завантажувачі запускатимуться повторно під час навігації. Що, якби ми не додали переспрямування в дію форми, а залишилися на поточній сторінці? SvelteKit виконував би оновлення у формі, як і раніше, але як і раніше повторно запустити всі завантажувачі для поточної сторінки, включаючи завантажувачі в макеті сторінки.
Чи можемо ми мати більш цілеспрямовані засоби анулювання наших даних? Наприклад, наші теги не редагувалися, тому в реальному житті ми не хотіли б повторно запитувати їх. Так, я вам показав лише поведінку форм за замовчуванням у SvelteKit. Ви можете вимкнути типову поведінку за допомогою надання зворотного дзвінка до use:enhance
. Потім SvelteKit надає посібник функції анулювання.
Завантаження даних під час кожної навігації є потенційно дорогим і непотрібним. Чи можу я кешувати ці дані, як я це роблю за допомогою таких інструментів, як react-query
? Так, просто інакше. SvelteKit дозволяє встановлювати (а потім враховувати) заголовки керування кеш-пам’яттю, які вже надає Інтернет. І я розповім про механізми недійсності кешу в наступній публікації.
Усе, що ми робили протягом цієї статті, використовує статичні дані та змінює значення в пам’яті. Якщо вам потрібно повернути все назад і почати спочатку, зупиніть і перезапустіть npm run dev
Процес вузла.
Підводячи підсумок
Ми ледь подряпали поверхню SvelteKit, але, сподіваюся, ви бачили достатньо, щоб бути в захваті від нього. Я не пам’ятаю, коли востаннє я вважав веб-розробку такою цікавою. З такими речами, як об’єднання, маршрутизація, SSR і розгортання, які виконуються з коробки, я витрачаю більше часу на кодування, ніж на налаштування.
Ось ще кілька ресурсів, які ви можете використовувати як наступні кроки для вивчення SvelteKit:
- Розповсюдження контенту та PR на основі SEO. Отримайте посилення сьогодні.
- Платоблокчейн. Web3 Metaverse Intelligence. Розширені знання. Доступ тут.
- джерело: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- Здатний
- МЕНЮ
- про це
- доступ
- рахунки
- дію
- дії
- Адам
- доданий
- доповнення
- адреса
- адмін
- просунутий
- впливати
- ВСІ
- Дозволити
- пліч-о-пліч
- вже
- завжди
- кількість
- та
- Інший
- відповідь
- будь
- додаток
- додаток
- застосування
- прикладної
- навколо
- масив
- стаття
- штучний
- призначений
- автоматичний
- автоматично
- доступний
- чекати
- назад
- фон
- банер
- бар
- основний
- перед тим
- КРАЩЕ
- Краще
- між
- Біт
- Black
- Блог
- Повідомлення в блозі
- синій
- Box
- приносити
- браузер
- помилки
- будувати
- побудований
- вбудований
- button
- Кеш
- call
- Виклики
- можливості
- випадок
- звичайно
- складні
- заміна
- ясно
- код
- Кодування
- color
- Колонка
- Приходити
- загальний
- Змагання
- компонент
- Компоненти
- конференції
- З'єднуватися
- З'єднувальний
- Консоль
- зміст
- Зручний
- може
- Курс
- покриття
- Обкладинки
- створювати
- створений
- створення
- Поточний
- В даний час
- дані
- Database
- дефолт
- Визначає
- затримка
- затримки
- розгортання
- дизайн
- деталі
- DEV
- розробка
- DID
- дисплей
- Ні
- справи
- Не знаю
- кожен
- в іншому місці
- досить
- Весь
- цілісність
- помилка
- і т.д.
- Навіть
- Кожен
- все
- приклад
- збуджений
- Збудження
- існує
- дорогий
- експорт
- реально
- особливість
- кілька
- Поля
- філе
- Файли
- в кінці кінців
- кінець
- Пожежа
- Перший
- виправляти
- плоский
- після
- назавжди
- форма
- формат
- форми
- знайдений
- каркаси
- від
- Повний
- веселощі
- функція
- функціональність
- Функції
- отримати
- отримання
- Давати
- дає
- Глобальний
- Go
- мета
- йде
- буде
- захоплення
- Group
- Групи
- траплятися
- Жорсткий
- Заголовки
- допомога
- тут
- прихований
- ієрархія
- на вищому рівні
- тримає
- З надією
- Горизонтальний
- Як
- HTML
- HTTPS
- Я БУДУ
- уява
- імпорт
- значення
- вражаючий
- in
- У тому числі
- початковий
- вхід
- замість
- інтегрувати
- цікавий
- Вступ
- IT
- пунктів
- сам
- JavaScript
- ключ
- останній
- останній
- макет
- вивчення
- дозволяє
- рівень
- Li
- життя
- світло
- Ймовірно
- зв'язку
- список
- жити
- загрузка
- завантажувач
- погрузка
- вантажі
- Довго
- подивитися
- ВИГЛЯДИ
- пошук
- удача
- машини
- зробити
- РОБОТИ
- Робить
- управління
- керівництво
- Маржа
- Матерія
- засоби
- пам'ять
- просто
- злиття
- метод
- може бути
- mind
- Модулі
- більше
- рухатися
- переміщення
- множинний
- ім'я
- Названий
- nav
- Переміщення
- навігація
- необхідно
- Необхідність
- Нові
- наступний
- вузол
- нормальний
- номер
- об'єкт
- об'єкти
- ONE
- порядок
- Інше
- інакше
- власний
- приватність
- шлях
- Виконувати
- вибирати
- частина
- частин
- заповнювач
- plato
- Інформація про дані Платона
- PlatoData
- точка
- пошта
- Пости
- потенційно
- Готувати
- Проблема
- процес
- виробляти
- прогресивний
- проект
- обіцяє
- власність
- захищений
- забезпечувати
- забезпечує
- Тягне
- put
- питання
- Сировина
- Читати
- реальний
- справжнє життя
- Реальність
- червоний
- переадресовувати
- Незалежно
- залишатися
- запам'ятати
- видаляти
- надання
- надає
- запросити
- ресурси
- результати
- повертати
- повернення
- Умови повернення
- повернути
- Багаті
- корінь
- Маршрут
- маршрути
- прогін
- біг
- то ж
- зберегти
- бачачи
- служить
- комплект
- тінь
- Поділитись
- загальні
- Повинен
- Показувати
- простий
- просто
- з
- один
- Ковзати
- So
- деякі
- що в сім'ї щось
- Джерела
- витрачати
- старт
- почалася
- залишився
- заходи
- Стоп
- представляти
- Опори
- поверхню
- система
- таблиця
- TAG
- Приймати
- взяття
- балаканина
- Тандем
- цільове
- розповідає
- шаблон
- термінал
- Команда
- речі
- по всьому
- час
- назва
- до
- разом
- занадто
- інструменти
- Тур
- лікувати
- правда
- ПЕРЕГЛЯД
- Машинопис
- ui
- при
- Оновити
- Updates
- URL
- us
- використання
- користувач
- значення
- Цінності
- різний
- через
- вид
- чекати
- хотів
- способи
- Web
- веб -компоненти
- Веб-розробка
- Що
- який
- білий
- волі
- виграти
- без
- чудовий
- Work
- працює
- вартість
- б
- запис
- Ти
- вашу
- зефірнет