ストアの自動サブスクライブ
リスト2の、ストアをサブスクライブ/アンサブスクライブする実装には、簡略化した記述方法が用意されています。
図1と同じ挙動となるp002-auto-subscriptionsサンプルで説明します。このサンプルで、カウンター値を表示するコンポーネントの実装はリスト4の通りです。
<script lang="ts"> import { count } from '$lib/store'; </script> <div class="container"> <div>CountDisplayコンポーネント</div> <div class="count">{$count}</div> <!--(1)--> </div>
<script>部でインポートしたcountストアを利用して、(1)の通り「$count」と$を付与して記述することで、そのストアの内容を表示するとともに、サブスクライブ/アンサブスクライブを自動的に行ってくれます。
読み取り可能なストアとDerivedストア
これまで利用してきた書き込み可能なストアのほかに、Svelteで利用できる「読み取り可能なストア」「Derivedストア」について、現在日時を取得して画面に表示する図3のサンプルで説明します。
図3のページ全体に対応するコンポーネント(+page.svelteファイル)の記述はリスト5の通りです。リスト4同様、ストア名に「$」を付与して記述します。
<h3>読み取り可能なストア</h3> <div>{$dateTime}</div> <h3>Derivedストア</h3> <div>{$formattedDateTime}</div>
読み取り可能なストア
読み取り可能なストアは、読み取りだけが可能で、書き込みができないストアです。図3のサンプルでは、store.tsにリスト6の通り実装されています。
export const dateTime = readable( // ...(1) // ストアの初期値 ...(2) new Date(), // サブスクライブ関連処理 ...(3) set => { // サブスクライブ時の処理 ...(4) const intervalId = setInterval(() => { set(new Date()); }, 1000); // アンサブスクライブ時の処理 ...(5) return () => { clearInterval(intervalId); } });
読み取り可能なストアは、(1)のreadable関数で定義します。関数の第1引数(2)にはストアの初期値、第2引数(3)にはサブスクライブ/アンサブスクライブ時の処理を定義した関数を渡します。
(3)の関数にはストアの値を設定するset関数が渡されるので、それを利用してサブスクライブ時の処理を記述します。ここでは(4)で、setInterval関数を利用して定期的にset関数を実行し、現在日時を設定するようにします。一方、アンサブスクライブ時の処理は(3)の関数の戻り値として記述します。ここでは(5)でclearInterval関数を実行して、サブスクライブ時に開始した定期実行を停止します。
Derivedストア
Derivedストアは、他のストアをもとにして導出されるストアです。Svelteのコンポーネントにおけるリアクティブ宣言や、Vue.jsのコンポーネントにおける算出プロパティと似た機能といえます。図3のサンプルでは、store.tsにリスト7の通り実装されています。
export const formattedDateTime = derived( // ...(1) // もとにするストア ...(2) dateTime, // ストアの値(ここでは日時をフォーマットして返却) ...(3) $dt => formatter.format($dt) );
Derivedストアは、(1)のderived関数で定義します。関数の第1引数(2)にはもとにするストア、第2引数(3)にはストアの値を返却する関数を渡します。ここではformatter.formatメソッドで、dateTimeストアに格納された日時をフォーマットして返します。
なお(3)で利用しているformatterは、リスト8の通り定義しています。Intl.DateTimeFormatメソッドの利用法は、Mozillaが公開しているドキュメントも参考にしてください。
const formatter = new Intl.DateTimeFormat('ja-JP', { dateStyle: 'medium', timeStyle: 'medium' });