Svelte

.svelte компонент: script, разметка, стили

Разработчик открывает файл Card.svelte и видит три части в одном месте: вверху JavaScript, посередине разметка, внизу стили. Возникает вопрос из мира React: разве смешивать всё в одном файле - не плохо? В Svelte это устроено так намеренно. Один .svelte файл - это один компонент целиком: логика, разметка и стили лежат рядом, а стили автоматически изолированы от остального приложения. Класс card в одном компоненте не сломает класс card в другом - компилятор позаботится об этом сам.

  • Дизайн-системы на Svelte: каждый элемент (кнопка, инпут, модалка) - отдельный .svelte файл со своими стилями
  • Компонентные библиотеки вроде Skeleton и Flowbite Svelte распространяют интерфейс именно набором .svelte файлов
  • Командная разработка: правка стилей одного компонента не задевает остальные благодаря изоляции
  • Документация svelte.dev строит интерактивные примеры из небольших самодостаточных .svelte компонентов
  • Перенос компонента в другой проект сводится к копированию одного файла со всем содержимым

Предварительные знания

  • HTML и CSS на базовом уровне: теги, классы, селекторы
  • JavaScript: объявление переменных и функций, импорт модулей
  • Готовый каркас SvelteKit из предыдущего урока

Три части .svelte файла

Файл .svelte состоит максимум из трёх частей, и порядок привычный: сначала тег script с логикой, затем разметка, в конце тег style. Логика - это обычный JavaScript или TypeScript: переменные, функции, импорты. Разметка - почти обычный HTML, в который можно вставлять выражения. Стили в теге style применяются только к этому компоненту. Любую из частей можно опустить.

Фигурные скобки в разметке - это вставка JavaScript-выражения. Запись {name} подставит значение переменной, а внутри атрибута onclick живёт обычная стрелочная функция. Переменная count объявлена через руну `$state`, поэтому при её изменении компилятор обновит соответствующий текст на странице.

  • Тег script: логика компонента, выполняется один раз при создании экземпляра
  • Разметка: HTML с вставками выражений в фигурных скобках
  • Тег style: CSS, по умолчанию изолированный в пределах компонента

Для TypeScript к тегу указывают атрибут lang со значением ts: запись script с lang равным ts включает проверку типов в этом компоненте. Всё остальное в файле работает так же.

Что означают фигурные скобки в разметке .svelte компонента, например запись {name}?

Изолированные стили

Главная особенность тега style в Svelte - изоляция. Селекторы внутри него применяются только к разметке этого компонента, а не ко всей странице. Компилятор находит элементы компонента, добавляет им уникальный класс вида svelte-хэш и дописывает этот класс в селекторы. В результате правило для класса title в одном компоненте никак не заденет такой же класс title в другом.

Оба компонента используют класс box, но стили не перемешиваются: Alert останется красным, Note - синим. Компилятор изолировал каждый набор правил. Это снимает целый класс проблем больших проектов, где глобальные стили незаметно перетирают друг друга.

ЗаписьОбласть действия
Селектор в теге styleТолько разметка этого компонента
:global(селектор)Выход из изоляции, применяется глобально
Стили в src/app.cssГлобально для всего приложения

Если стиль нужно применить ко всему приложению или к содержимому, пришедшему извне, изоляцию можно отключить через обёртку :global вокруг селектора. Без неё селектор сработает только на собственной разметке компонента, и стиль для дочернего компонента может не примениться.

Почему класс .box в компоненте Alert.svelte не влияет на класс .box в компоненте Note.svelte?

Импорт и использование компонентов

Сила компонентов в том, что один вкладывается в другой. Чтобы использовать компонент, его импортируют как обычный модуль в теге script, а затем вставляют в разметку как тег. Имя тега компонента пишется с заглавной буквы - так Svelte отличает компонент от обычного HTML-элемента вроде div или p.

Содержимое между открывающим и закрывающим тегами компонента - это его дети. В примере заголовок, абзац и кнопка переданы внутрь Card. Чтобы Card отобразил эту вложенную разметку, он использует сниппеты и команду рендера, о которых речь в уроках про шаблоны и props. Пока важно одно: компоненты вкладываются друг в друга так же естественно, как обычные теги.

  1. Импортировать компонент в теге script указанием пути к .svelte файлу
  2. Вставить его в разметку как тег с заглавной буквы
  3. При необходимости передать данные через атрибуты-props и вложенную разметку

Имя при импорте задаёт разработчик, и оно же становится именем тега. Импорт компонента под именем Card даёт тег Card, импорт под именем ProductCard - тег ProductCard. Имя файла и имя при импорте не обязаны совпадать, но совпадение упрощает чтение кода.

Почему имя компонента в разметке пишут с заглавной буквы, например Card, а не card?

Связь с другими темами

Компонент - базовый кирпич Svelte. Дальше курс учит наполнять и связывать кирпичи:

  • Структура проекта SvelteKit — Компоненты живут в src/lib и src/routes. Без каркаса некуда их класть
  • Синтаксис шаблонов — Разметка компонента оживает через выражения, условия и циклы
  • Входные параметры через `$props` — Чтобы компонент принимал данные снаружи, ему нужны props

Итог

  • Файл .svelte - это один компонент: блок script с логикой, разметка как обычный HTML и тег style со стилями
  • Все три части необязательны: компонент может состоять только из разметки или только из логики и разметки
  • Стили внутри тега style автоматически изолированы (scoped): они применяются только к разметке этого компонента
  • Компилятор добавляет уникальный класс к элементам компонента, поэтому одинаковые имена классов в разных файлах не конфликтуют
  • Компонент подключается обычным импортом и используется как тег с заглавной буквы внутри разметки другого компонента

Связанные уроки

  • sv-02-setup-sveltekit — Компоненты живут внутри каркаса проекта, поэтому сначала нужно понять структуру SvelteKit
  • sv-04-template-syntax — Разметка компонента наполняется выражениями, условиями и циклами - это следующий урок
  • sv-09-props — Чтобы передавать данные в компонент, нужны входные параметры через `$props`
.svelte компонент: script, разметка, стили

0

1

Войти