コンポーネントからイベントを発生
子コンポーネントでイベントを発生させて、親コンポーネントでそれを受け取り処理を行うことができます。図7のサンプルは、子コンポーネントで「購入」ボタンが押されたときにイベントが発生し、それを親コンポーネント側で受け取って、イベントに含まれるメーカーと機種をダイアログで表示します。
イベントを発生する子コンポーネントの<script>部をリスト7に示します。
<script lang="ts"> import { createEventDispatcher } from 'svelte'; // ...(1) (略) const dispatch = createEventDispatcher(); // ...(2) // ボタンクリック時の処理 ...(3) const buttonClicked = () => { dispatch('purchase', { vendor, model }); // イベントを発生 }; </script>
(1)でインポートしたcreateEventDispatcher関数を利用して、(2)でdispatch関数を生成し、ボタンクリック時に実行されるbuttonClicked関数(3)内でdispatch関数を実行してイベントを発生させます。dispatch関数の第1引数(purchase)はイベント名、第2引数(vendor、model)はイベント変数です。
一方、イベントを受け取る親コンポーネントの実装はリスト8となります。
<script lang="ts"> import Android from './Android.svelte'; const handlePurchaseEvent = (event: CustomEvent) => { // ...(1) alert(`購入:${event.detail.vendor} / ${event.detail.model}`); // ...(1a) } </script> <Android vendor="OPPO" model="Reno11 A" on:purchase={handlePurchaseEvent}></Android> <!--(2)--> (以下略)
子コンポーネントを記述する際、(2)の通りon:purchase属性にイベントハンドラー(handlePurchaseEvent関数)を設定して、purchaseイベントを受け取ります。handlePurchaseEvent関数(1)では、CustomEvent型の変数eventを関数の引数として受け取り、そのdetailプロパティから取得したイベント変数を(1a)でダイアログに表示します。
ルーティングと共有コンポーネント
SvelteKitプロジェクトでは、複数のURLに対応してページを出しわけるルーティング機能が利用できます。これまで利用してきたsrc/routes/+page.svelteはサブパスを含まないURL(http://localhost:5173/)に対応する一方、src/routes/<サブパス>フォルダーの中に+page.svelteファイルを配置することで、サブパスを含むURL(http://localhost:5173/<サブパス>)に対応するWebページを実装できます。図8のサンプルにおいて、サブパスを含まないURL(「/」パス)ではWindowsパソコンのラインナップを表示します。
図8で「Mac」のリンクをクリックすると、「/mac」パスを含むURLに遷移して、Macのラインナップを表示します。また図8、9のいずれにも共通して「この夏の注目パソコン」というヘッダーを表示します。
図8、9のサンプルにおける、srcフォルダー以下のフォルダー構成を図10に示します。「/」パスに対応するsrc/routesフォルダーと「/mac」パスに対応するsrc/routes/macフォルダーのそれぞれに、ページ全体に対応する+page.svelteファイルと、各ページで利用する子コンポーネントのファイル(Windows.svelte、Mac.svelte)を配置します。また、各ページ共通で利用するヘッダーに対応するコンポーネントのファイル(header.svelte)はsrc/libフォルダーに配置します。
「/」パスのページ全体に対応するsrc/routes/+page.svelteの実装を、リスト9に示します(src/routes/macサブフォルダーの+page.svelteも基本的な実装内容は同一です)。
<script lang="ts"> // コンポーネントをインポート ...(1) import Windows from './Windows.svelte'; // ...(1a) import Header from '$lib/header.svelte'; // ...(1b) </script> <!-- 各ページ共通のヘッダー ...(2)--> <Header></Header> <!-- ページ見出しとリンク ...(3)--> <h3>Windows <a href="/mac">Mac</a></h3> <!-- 子コンポーネント ...(4)--> <Windows vendor="Microsoft" model="Surface Pro"></Windows> <Windows vendor="Dell" model="XPS 15インチ"></Windows> <Windows vendor="富士通" model="FMV LIFEBOOK UH"></Windows>
(1)で、コンポーネント内で利用する他のコンポーネントをインポートします。同一フォルダーにあるコンポーネントは(1a)の通り「./」で始まる相対パスで参照しますが、src/libフォルダーにあるコンポーネントは(1b)の通り、参照元にかかわらずどこからでも$lib/
で始まるパスで参照できます。(1a)でインポートしたコンポーネントは(4)で、(1b)でインポートしたヘッダーのコンポーネントは(2)で、それぞれ利用しています。
他ページへのリンクは(3)の通り、HTML同様<a href>でリンク先のパスを指定します。ここではMacのページに対応する「/mac」を指定しています。
まとめ
本記事では、SvelteKitプロジェクトの構成と基本的な利用法、SvelteでWebページの表示を構成するコンポーネントの実装方法を説明しました。次回は、コンポーネント内のデータと表示を同期するリアクティブな処理とデータバインディングについて解説します。