Пропсы и руна $props
Руна $props объявляет входные данные компонента — как параметры функции, но для UI.
«Компонент без пропсов — это монолог. Пропсы превращают его в диалог с родителем.»
Компоненты становятся по-настоящему полезными, когда их можно переиспользовать с разными данными. Карточка пользователя должна показывать любого пользователя, кнопка — любой текст. Данные, которые родитель передаёт ребёнку, называются пропсами (свойствами). В Svelte 5 компонент объявляет свои пропсы руной $props.
Синтаксис элегантен: вы деструктурируете пропсы прямо из вызова $props(). Это сразу видно как контракт компонента — что он принимает снаружи. Можно задавать значения по умолчанию и переименовывать.
<!-- UserCard.svelte -->
<script>
let { name, age = 18, role = 'студент' } = $props();
</script>
<article>
<h3>{name}</h3>
<p>{age} лет, {role}</p>
</article>Родитель использует компонент как HTML-тег, передавая пропсы атрибутами:
<!-- родитель -->
<script>
import UserCard from './UserCard.svelte';
</script>
<UserCard name="Аня" age={17} />
<UserCard name="Борис" role="наставник" />Заметьте: строку можно передать в кавычках, а число или выражение — в фигурных скобках. Пропс age у Бориса не передан, поэтому подставится значение по умолчанию — 18. Пропсы в Svelte однонаправлены: данные текут сверху вниз, от родителя к ребёнку. Это делает поток предсказуемым.
Как это работает под капотом
Пропсы — это, по сути, аргументы функции-компонента. Смоделируем фабрику компонентов с пропсами и значениями по умолчанию на чистом JS.
// Компонент как функция, принимающая пропсы
function UserCard(props) {
const { name, age = 18, role = 'студент' } = props; // дефолты
return `<article><h3>${name}</h3><p>${age} лет, ${role}</p></article>`;
}
console.log(UserCard({ name: 'Аня', age: 17 }));
console.log(UserCard({ name: 'Борис', role: 'наставник' })); // age по умолчаниюПопробуй сам ▶ — вставь код в консоль браузера (F12 → Console) и нажми Enter, чтобы увидеть вывод.
В реальном Svelte пропсы ещё и реактивны: если родитель передаёт реактивное значение, обновление прилетит вниз автоматически. Но базовая ментальная модель — «пропсы это параметры» — верна.
Родитель
|
| name="Аня" age={17}
v
$props() -> { name, age, role }
|
v
разметка UserCard использует значенияЧастые ошибки
- Пытаться записывать в пропс напрямую. Пропсы текут сверху вниз; для двусторонней связи есть
$bindable. - Путать строку и выражение.
age="17"передаст строку, аage={17}— число. - Забывать значения по умолчанию, из-за чего компонент падает на отсутствующих пропсах.
Best practices
- Задавайте разумные значения по умолчанию — это делает компонент устойчивым.
- С TypeScript типизируйте пропсы:
let { name }: { name: string } = $props(). - Держите список пропсов небольшим; если их много, возможно, компонент делает слишком многое.
Проектирование удобного интерфейса компонента
Список пропсов — это публичный контракт компонента, по сути его API. Хорошо спроектированный набор пропсов делает компонент приятным в использовании, плохой — превращает каждое применение в борьбу. Несколько ориентиров из практики. Давайте пропсам говорящие имена, отражающие смысл, а не реализацию. Снабжайте необязательные пропсы разумными значениями по умолчанию, чтобы в простом случае компонент работал без лишней настройки. Не раздувайте список: если у компонента десяток пропсов, это сигнал, что он, возможно, делает слишком много и его стоит разбить. С TypeScript обязательно типизируйте пропсы — тип служит и документацией, и страховкой от опечаток. Помните, что пропсы однонаправлены: компонент получает данные сверху и не должен пытаться их перезаписывать. Если ребёнку нужно сообщить родителю об изменении, для этого есть колбэки, о которых мы поговорим в следующем уроке.
Итог: $props объявляет входные данные компонента через деструктуризацию, поддерживает значения по умолчанию и реализует однонаправленный поток данных сверху вниз.