Базовая разметка
Разметка внутри компонента Svelte может рассматриваться как HTML++.
Теги
Тег в нижнем регистре, такой как <div>
, обозначает обычный HTML-элемент. Тег с заглавной буквы или тег, использующий нотацию с точками, такой как <Widget>
или <my.stuff>
, указывает на компонент.
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget />
</div>
Атрибуты элемента
По умолчанию атрибуты работают точно так же, как их HTML-аналоги:
<div class="foo">
<button disabled>элемент недоступен</button>
</div>
Как и в HTML, значения могут быть без кавычек:
<input type=checkbox />
Значения атрибутов могут содержать выражения JavaScript:
<a href="page/{p}">page {p}</a>
Или они могут быть выражениями JavaScript:
<button disabled={!clickable}>...</button>
Булевы атрибуты включаются в элемент, если их значение является истинным, и исключаются, если оно ложное.
Все остальные атрибуты включаются, если их значение не является нулевым (null
или undefined
).
<input required={false} placeholder="Это поле ввода не обязательно" />
<div title={null}>У этого div нет атрибута title</div>
Когда имя атрибута и значение совпадают (name={name}
), их можно заменить на {name}
:
<button {disabled}>...</button>
<!-- то же самое, что и
<button disabled={disabled}>...</button>
-->
Свойства компонента
По соглашению, значения, передаваемые компонентам, называются свойствами или пропсами, а не атрибутами, которые являются особенностью DOM.
Как и в случае с элементами, name={name}
можно заменить на сокращение {name}
:
<Widget foo={bar} answer={42} text="привет" />
Атрибуты с использованием оператора распространения позволяют передавать множество атрибутов или свойств элементу или компоненту одновременно.
Элемент или компонент может иметь несколько атрибутов распространения, перемежая их с обычными атрибутами:
<Widget {...things} />
События
Прослушивание событий DOM возможно путём добавления атрибутов к элементу, которые начинаются с on
. Например, чтобы прослушивать событие click
, добавьте атрибут onclick
к кнопке:
<button onclick={() => console.log('нажато')}>нажми меня</button>
Атрибуты событий чувствительны к регистру. onclick
прослушивает событие click
, а onClick
прослушивает событие Click
, что является другим событием. Это позволяет вам прослушивать пользовательские события, которые содержат заглавные буквы.
Поскольку события — это просто атрибуты, к ним применяются те же правила, что и для атрибутов:
- вы можете использовать сокращённую форму:
<button {onclick}>нажми меня</button>
- вы можете использовать их с оператором распространения:
<button {...thisSpreadContainsEventAttributes}>нажми меня</button>
С точки зрения времени, атрибуты событий всегда срабатывают после событий от привязок (например, oninput
всегда срабатывает после обновления bind:value
). Внутри некоторые обработчики событий прикрепляются напрямую с помощью addEventListener
, в то время как другие являются делегированными.
При использовании атрибутов событий ontouchstart
и ontouchmove
обработчики являются пассивными для повышения производительности. Это значительно улучшает отзывчивость, позволяя браузеру немедленно прокручивать документ, а не ждать, вызовет ли обработчик события event.preventDefault()
.
В очень редких случаях, когда вам нужно предотвратить эти стандартные события, вы должны использовать on
вместо этого (например, внутри действия).
Делегирование событий
Чтобы уменьшить использование памяти и повысить производительность, Svelte использует технику, называемую делегированием событий. Это означает, что для определённых событий — см. список ниже — один обработчик событий на корневом элементе приложения отвечает за выполнение любых обработчиков на пути события.
Есть несколько нюансов, о которых стоит помнить:
- когда вы вручную вызываете событие с делегированным слушателем, убедитесь, что вы установили опцию
{ bubbles: true }
, иначе оно не дойдет до корневого элемента приложения - при использовании
addEventListener
напрямую избегайте вызоваstopPropagation
, иначе событие не дойдет до корневого элемента, и обработчики не будут вызваны. Аналогично, обработчики, добавленные вручную внутри корневого элемента, будут выполняться до обработчиков, добавленных декларативно глубже в DOM (например, с помощьюonclick={...}
), как в фазе захвата, так и в фазе всплытия. По этим причинам лучше использовать функциюon
, импортированную изsvelte/events
, вместоaddEventListener
, так как это обеспечит сохранение порядка и правильную обработкуstopPropagation
.
Следующие обработчики событий делегируются:
beforeinput
click
change
dblclick
contextmenu
focusin
focusout
input
keydown
keyup
mousedown
mousemove
mouseout
mouseover
mouseup
pointerdown
pointermove
pointerout
pointerover
pointerup
touchend
touchmove
touchstart
Текстовые выражения
JavaScript-выражение можно включить в текст, обернув его фигурными скобками:
{expression}
Фигурные скобки можно включить в шаблон Svelte, используя их HTML-сущности: {
, {
, или {
для {
и }
, }
, или }
для }
.
Если вы используете регулярное выражение (RegExp
) в литеральной нотации, вам нужно обернуть его в скобки:
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
Выражение будет преобразовано в строку и экранировано, чтобы предотвратить инъекции кода. Если вы хотите отобразить HTML, используйте тег {@html}
:
{@html potentiallyUnsafeHtmlString}
Комментарии
Вы можете использовать HTML-комментарии внутри компонентов:
<!-- это комментарий! --><h1>Привет, мир</h1>
Комментарии, начинающиеся с svelte-ignore
, отключают предупреждения для следующего блока разметки. Обычно это предупреждения по доступности; убедитесь, что вы отключаете их по уважительной причине:
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />
Вы можете добавить специальный комментарий, начинающийся с @component
, который будет отображаться при наведении на имя компонента в других файлах:
<!--
@component
- Вы можете использовать здесь markdown.
- Вы также можете использовать здесь блоки кода.
- Использование:
```html
<Main name="Arethra">
```
-->
<script>
let { name } = $props();
</script>
<main>
<h1>
Привет, {name}
</h1>
</main>