Basic markup
Svelte コンポーネント内のマークアップは、HTML++ と考えることができます。
Tags
小文字のタグ (<div> のようなもの) は通常の HTML 要素を表します。一方、大文字で始まるタグやドット表記を使用したタグ (<Widget> や <my.stuff> など) は コンポーネント を表します。
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget />
</div>Element attributes
デフォルトでは、属性は HTML のそれと同じように動作します。
<div class="foo">
<button disabled>can't touch this</button>
</div>HTML と同様に、値は引用符なしでも指定することができます。
<input type=checkbox />属性値には JavaScript の式を含めることができます。
<a href="page/{p}">page {p}</a>または、それ自体を JavaScript の式にすることも可能です。
<button disabled={!clickable}>...</button>Boolean の属性は、その値が truthy であれば要素に含まれ、falsy であれば除外されます。
その他の属性は、値が nullish (null または undefined) でない限り含まれます。
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>単一の式を引用符で囲むことは値のパース方法に影響しませんが、Svelte 6 では値が文字列に変換されるようになります:
<button disabled="{number !== 42}">...</button>
属性名と値が一致する場合 (name={name})、{name} という形で簡略化できます。
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->Component props
慣習として、コンポーネントに渡される値は、DOM の機能である 属性 ではなく、プロパティ または props と呼ばれます。
要素の場合と同様に、name={name} は {name} の短縮形に置き換えることができます。
<Widget foo={bar} answer={42} text="hello" />Spread attributes
スプレッド属性(Spread attributes) を使用すると、複数の属性やプロパティを一度に要素やコンポーネントに渡すことができます。
要素やコンポーネントは複数のスプレッド属性を置くことができますし、通常の属性と一緒に使用することもできます。順序が重要です。things.a が存在する場合、a="b" より優先されますが、c="d" は things.c より優先されます。
<Widget a="b" {...things} c="d" />Events
DOM イベントを監視するには、要素に on で始まる属性を追加します。例えば、click イベントを監視するには、ボタンに onclick 属性を追加します:
<button onclick={() => console.log('clicked')}>click me</button>イベント属性は大文字小文字を区別します。onclick は click イベントを監視し、onClick は異なる Click イベントを監視します。これにより、大文字を含むカスタムイベントを監視することが可能になります。
イベントは単なる属性であるため、属性と同じルールが適用されます:
- 短縮形を使用できます:
<button {onclick}>click me</button> - スプレッドも使用できます:
<button {...thisSpreadContainsEventAttributes}>click me</button>
タイミング的に、イベント属性は常にバインディングのイベントの後に発火します (例えば、oninput は bind:value の更新後に発火します)。内部では、一部のイベントハンドラーは addEventListener を使用して直接アタッチされ、その他は 委任(delegate) されます。
ontouchstart や ontouchmove イベント属性を使用する場合、ハンドラーは passive として動作し、パフォーマンスが向上します。これにより、イベントハンドラーが event.preventDefault() を呼び出すかどうかを待つのではなく、ブラウザが即座にドキュメントをスクロールできるようになり、レスポンシブ性が大幅に改善されます。
これらのイベントのデフォルト動作を防ぐ必要がある非常に稀な場合には、代わりに on を使用するべきです (例えば action 内で)。
Event delegation
メモリ消費を減らし、パフォーマンスを向上させるため、Svelte はイベントデリゲーション (event delegation) というテクニックを使用しています。これは、以下のリストにある特定のイベントについては、アプリケーションルートの単一のイベントリスナーがイベントのパス上のハンドラーを実行する役割を担うことを意味します。
注意すべきポイントがいくつかあります:
- 委任されたリスナー(delegated listener)でイベントを手動でディスパッチする場合、
{ bubbles: true }オプションを設定してください。さもないとアプリケーションルートに到達しません。 addEventListenerを直接使用する場合、stopPropagationを呼び出さないようにしてください。そうしないと、イベントがアプリケーションルートに到達せず、ハンドラーが実行されなくなります。同様に、アプリケーションルート内に手動で追加されたハンドラーは、DOM の深い場所に宣言的に追加されたハンドラー (例えばonclick={...}など) よりも 前に 実行されます (キャプチャおよびバブリングフェーズの両方で)。これらの理由から、addEventListenerよりもsvelte/eventsからインポートされるon関数を使用する方が、順序が保持され、stopPropagationが正しく処理されるため推奨されます。
以下のイベントハンドラーが委任(delegate)されます:
beforeinputclickchangedblclickcontextmenufocusinfocusoutinputkeydownkeyupmousedownmousemovemouseoutmouseovermouseuppointerdownpointermovepointeroutpointeroverpointeruptouchendtouchmovetouchstart
Text expressions
JavaScript 式は中括弧 {} で囲むことでテキストとして含めることができます。
{expression}null や undefined となる式は省略されます; それ以外はすべて String に変換されます。
中括弧は、その HTML エンティティ 文字列を使用することで Svelte テンプレート内に含めることができます。{ の場合は {, {, または {、} の場合は }, }, または } を使用します。
正規表現 (RegExp) の リテラル表記 を使用する場合、それを括弧で囲む必要があります。
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>式は文字列化され、コードインジェクションを防ぐためにエスケープされます。HTML をレンダリングしたい場合は、代わりに {@html} タグを使用してください。
{@html potentiallyUnsafeHtmlString}渡される文字列をエスケープするか、または自分がコントロールできる値でのみ埋めるようにして、XSS 攻撃 を防止してください。
Comments
コンポーネント内で HTML コメントを使用することができます。
<!-- this is a comment! --><h1>Hello world</h1>svelte-ignore で始まるコメントは、その次にくるマークアップブロックに対する警告を無効にします。通常、これらはアクセシビリティに関する警告であることが多いですが、適切な理由がある場合にのみ無効化するようにしてください。
<!-- svelte-ignore a11y_autofocus -->
<input bind:value={name} autofocus />@component で始まる特別なコメントを追加することで、他のファイルでコンポーネント名にカーソルを合わせたときに表示されるコメントを作成できます。
<!--
@component
- You can use markdown here.
- You can also use code blocks here.
- Usage:
```html
<Main name="Arethra">
```
-->
<script>
let { name } = $props();
</script>
<main>
<h1>
Hello, {name}
</h1>
</main>