ストアのバインディング
コンポーネント内の変数と同様に、ストアについても、コンポーネント内の入力部品と紐づけるバインディング機能を利用できます。この機能を図4のサンプルで説明します。
このサンプルはストアの内容を表示するPhoneDisplayコンポーネントと、ストアの値を変更するPhoneInputコンポーネントから構成されており、PhoneInputコンポーネントでスマートフォンのブランドと機種を変更すると、変更内容がPhoneDisplayコンポーネントに反映されます。
このサンプルで利用するストアはリスト9の通りです。スマートフォンのブランド(brand)と機種(name)に対応する書き込み可能なストアを定義しています。
export const brand = writable('Apple');
export const name = writable('iPhone 16');
リスト9のストアを参照して画面に表示するPhoneDisplayコンポーネントの記述はリスト10の通りです。brand、nameストアの内容を表示します。
<script lang="ts">
import { brand, name } from '$lib/store';
</script>
<div class="container">
PhoneDisplayコンポーネント
<div>メーカー:{$brand}</div>
<div>機種名: {$name}</div>
</div>
一方、リスト9のストアを変更するPhoneInputコンポーネントの記述はリスト11の通りです。
<script lang="ts">
import { brand, name } from '$lib/store'; // ...(1)
// brandとnameをリセットする処理 ...(2)
const resetToApple = () => {
$brand = 'Apple';
$name = 'iPhone 16';
};
</script>
<div class="container">
PhoneInputコンポーネント
<div>
<!-- $brandにバインディング ...(3)-->
<select bind:value={$brand}>
<option value="Apple">Apple</option>
<option value="Google">Google</option>
<option value="motorola">motorola</option>
<option value="Xiaomi">Xiaomi</option>
</select>
<!-- $nameにバインディング ...(4)-->
<input type="text" bind:value={$name} />
</div>
<!-- resetToAppleメソッドを実行するボタン ...(5)-->
<button on:click={resetToApple}>Apple iPhone 16にリセット</button>
</div>
<script>部の(1)でbrand、nameストアをインポートしています。(2)は後述するボタンクリック時に、ストアの内容をリセットする処理です。
一方、表示内容の定義では、(3)の<select>要素と(4)の<input>要素に「bind:value」属性を記述することで、brandストアと<select>要素、nameストアと<input>要素を、それぞれバインディングしています。この記述により、セレクトボックスやテキストボックスを変更すると、変更された内容がストアに反映されます。(5)では、(2)のリセット処理を実行するボタンを定義しています。
ストアの自動サブスクライブ同様、「$brand」「$name」と$をつけて記述することにより、ストアを普通の変数のように扱って、バインディングや代入が行えます。
まとめ
本記事では、Webページ全体の状態を統一的に管理できる、Svelteのストア機能を説明しました。Svelteの標準機能として組み込まれているため、ライブラリのインストールやプロジェクト設定の変更なしで、すぐに使い始めることができます。ストア名に「$」を付与することで、サブスクライブ関連の処理を隠蔽できるため、開発者はシンプルにストアのデータ内容に集中して実装が行えます。
本連載では、Svelteの利用法を、順を追って紹介してきました。SvelteにはSvelteKitを含め、本連載で紹介した以外にさまざまな機能が備わっています。本連載を通してSvelteに興味を持った方は、公式ページで提供されているSvelteやSvelteKitのチュートリアルで、Svelteをより深く体験してみてはいかがでしょうか。
