TL;DR
- Svelte 公式チュートリアルの Advanced Svelte。Svelte 5 のリアクティビティの応用、スニペット、モーション、バインディング、特殊要素、
<script module>を扱う。 <svelte:fragment>や<svelte:component>、tweened、spring、<script context="module">は非推奨になり、スニペットやTween、Springなどに置き換わった。
内容
Advanced reactivity
$state.raw を使うと、個々のプロパティの変更を検知するオーバーヘッドがなくなる。そのかわり、person.age += 1 のようにプロパティを変えても UI は更新されず、オブジェクトを再代入したときだけ更新される。
$state や $derived はクラスのプロパティにも使える。プロパティを private にして getter / setter を用意すれば、値に制限をかけられる。
svelte/reactivity は、Map、Set、Date、URL、URLSearchParams のリアクティブ版(SvelteDate など)を提供している。これらのメソッドは Proxy を介さないので、$state で包むより効率がよい。
Reusing content
コンポーネント内で再利用するマークアップは、スニペットで定義して {@render} で描画する。引数も受け取れる。
{#snippet monkey(emoji, description)}
<tr><td>{emoji}</td><td>{description}</td></tr>
{/snippet}
{@render monkey("🙈", "see no evil")}スニペットは Props として他のコンポーネントに渡せるので、表示の仕方を親で決められる。コンポーネントのタグの中で宣言したスニペットはその Props になり、スニペットでない中身は children として渡される。
Motion
svelte/motion の Tween クラスは、時間をかけて値が変わる状態を作る。delay、duration、easing、interpolate を指定でき、書き込み用の target と読み取り用の current を持つ。Spring クラスは値がばねのように変わる状態を作り、頻繁に変わる値に向いている。stiffness、damping、precision を指定できる。tweened と spring は非推奨になった。
Advanced bindings
contenteditable 属性を持つ要素は textContent と innerHTML をバインドできる。$bindable() を使うと Props をバインドできるが、単方向データフローが崩れるので、Vue と同じく極力使わない。特に信頼できる唯一の情報源がない場合は避ける。bind:this でコンポーネントのインスタンスをバインドすると、子が export した関数を親から呼べる。
Special elements
<svelte:fragment> はスニペットで、<svelte:component> は v5 でコンポーネントが動的になったことで、<svelte:self> は自分自身を import できるようになったことで、それぞれ不要になった。
<svelte:document> を使うと、selectionchange のような Window では起きないイベントを listen できる。ただし mouseenter や mouseleave はすべてのブラウザの Document で起きるわけではないので、<svelte:body> を使う。
<svelte:boundary> は、子要素の描画や更新、$effect の中でエラーが起きたときに、その中身を破棄する。エラー時の表示は error と reset を受け取る failed スニペットに書く。イベントハンドラや非同期処理の後のように、描画の外で起きたエラーは捕捉できない。
<script module>
すべてのインスタンスで状態を共有するには <script module> を書く。<script context="module"> は非推奨になった。ここで export したものはモジュールからのエクスポートになるが、コンポーネント自体が default export なので、default export は使えない。
キーワード
- Svelte
- Props
- 単方向データフロー
- 信頼できる唯一の情報源
- ブラウザ
- Error Boundary
自分の理解
<svelte:boundary> は React の Error Boundary に似ている。{#await} は Suspense のような立ち位置だろうか。