SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Webページ用UIフレームワーク「Svelte」の活用

「Svelte」の活用に不可欠──プロジェクト構成とコンポーネント利用法を解説!

Webページ用UIフレームワーク「Svelte」の活用 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Svelteコンポーネントの基本

 以下では、生成したSvelteKitプロジェクトをもとに、Svelteコンポーネントを利用してWebページを実装する方法を説明します。

 Webページ全体に対応するコンポーネントのファイルは、表2、No.2に示したsrc/routes/+page.svelteファイルです。このファイルに実装を加えた図4のサンプルで、Svelteコンポーネントの基本的な実装方法を説明します。前回記事でも紹介した、ボタンのクリックでカウントが増加するサンプルです。

図4 Svelteコンポーネントの基本的なサンプル(p003-basic)
図4 Svelteコンポーネントの基本的なサンプル(p003-basic)

 図4の+page.svelteファイルを、リスト2に示します。

[リスト2]図4のSvelteコンポーネント(p003-basic/src/routes/+page.svelte)
<script lang="ts"> // 実装 ...(1)
  let count: number = 0; // ...(1a)
  const increment = () => { // ...(1b)
    count += 1;
  };
</script>

<!-- マークアップ ...(2)-->
<h1>コンポーネントのサンプル</h1>
<button on:click={increment}> <!--(2a)-->
  count is {count} <!--(2b)-->
</button>

<style> /* スタイル指定 ...(3)*/
  button { font-size: 20pt; }
</style>

 Svelteコンポーネント(*.svelteファイル)は、<script>タグ内に記述する実装(1)、表示内容のマークアップ(2)、<style>タグ内に記述するスタイル指定(3)からなります。これらの記述はいずれも任意で、どれかの要素を含まないこともできます。

 <script>タグの属性lang="ts"は、記述言語がTypeScriptであることを表します。実装はTypeScriptの標準的な記法で行えます。ここでは(1a)でカウントの変数countを0で初期化し、(1b)ではcountを1増やすincrement関数を実装しています。

 マークアップは(Svelte独自の記述を含んだ)HTMLで行います。(2a)のon:click={increment}は、ボタンのクリックイベント発生時に(1b)のincrement関数を実行することを表します。このようにon:<イベント名>={<処理>}でイベント発生時の処理を指定できます。また(2b)の通り{count}と、変数名を中括弧で囲って記述すると、その変数の内容をWebページに表示できます。

 <style>タグのスタイル指定は、標準的なCSSで記述します。ここではbuttonタグのスタイルを指定しています。

マークアップの条件分岐と繰り返し

 マークアップでは条件分岐や繰り返しの指定ができます。図5のサンプルでは、カウント値の条件分岐(5未満、5以上、10以上)による表示の出しわけと、カウント値配列の繰り返しによる表示を行います。

図5 条件分岐と繰り返しのサンプル(p004-if-each)
図5 条件分岐と繰り返しのサンプル(p004-if-each)

 条件分岐の記述はリスト3の通りです。(1)の#if、(2)の:else if、(3)の:elseで条件を指定し、条件指定の最後は(4)の/ifで閉じます。

[リスト3]マークアップの条件分岐記述(p004-if-each/src/routes/+page.svelte)
{#if count >= 10} <!--(1)-->
  <p>countは10以上</p>
{:else if count >= 5} <!--(2)-->
  <p>countは5以上</p>
{:else} <!--(3)-->
  <p>countは5未満</p>
{/if} <!--(4)-->

 繰り返しの記述はリスト4の通りです。(1)の#eachで繰り返しを指定します。countArray as itemは、countArray配列の各要素をitemとして参照する意味で、itemは(2)の記述で画面に表示させます。繰り返し範囲の最後は(3)の/eachで閉じます。なおcountArray配列は、カウンターが増えるごとにその値が末尾に追加される配列です(実装の詳細はサンプルコードを参照してください)。

[リスト4]マークアップの繰り返し記述(p004-if-each/src/routes/+page.svelte)
<div class="count-array">
  {#each countArray as item} <!--(1)-->
    <span>{item}</span> <!--(2)-->
  {/each} <!--(3)-->
</div>

複数コンポーネントの利用

 これまでのサンプルでは1つのコンポーネント(+page.svelte)でWebページ全体を記述しましたが、Webページの内容を複数コンポーネントで記述することもできます。図6のサンプルでは、1つのWebページ内に、iPhone、Android、Chromebookに対応した3つの子コンポーネント(*.svelteファイル)を表示しています。各コンポーネントにはメーカー、機種、在庫数が表示され、在庫追加ボタンをクリックすると在庫数が増加します。

図6 複数コンポーネントを利用したサンプル(p005-nested)
図6 複数コンポーネントを利用したサンプル(p005-nested)

 iPhoneに対応する子コンポーネント(iPhone.svelteファイル)はリスト5の通りです(Android、Chromebookに対応する子コンポーネントも実装内容はほぼ同一です)。

[リスト5]図6のiPhone子コンポーネント(p005-nested/src/routes/iPhone.svelte)
<script lang="ts">
  // プロパティ ...(1)
  export let vendor = 'Apple';
  export let model = '';
  export let count = 0;
</script>

<!-- プロパティ内容を表示 ...(2)-->
<div class="container">
  <div>【iPhone】</div>
  <div>メーカー:{vendor}</div>
  <div>機種:{model}</div>
  <div>在庫数:{count}</div>
</div>
(略:<style>要素)

 (1)の通りexport letと記述した変数はコンポーネントのプロパティとなり、外部から設定できるようになります。このプロパティは(2)のマークアップ部で参照して画面に表示されるようにします。

 一方、子コンポーネントを表示する親コンポーネント側の実装はリスト6となります。

[リスト6]図6の親コンポーネント(p005-nested/src/routes/+page.svelte)
<script lang="ts">
  // 子コンポーネントをインポート ...(1)
  import IPhone from './iPhone.svelte';
  import Android from './Android.svelte';
  import Chromebook from './Chromebook.svelte';
  // 在庫数 ...(2)
  let iPhoneCount = 0;
  let androidCount = 0;
  let chromebookCount = 0;
</script>

<!-- 在庫追加ボタン ...(3)-->
<button on:click={() => { iPhoneCount += 1; }}>iPhone在庫追加</button>
<button on:click={() => { androidCount += 1; }}>Android在庫追加</button>
<button on:click={() => { chromebookCount += 1; }}>Chromebook在庫追加</button>
<!-- 子コンポーネント ...(4)-->
<IPhone model="iPhone 15"
 count={iPhoneCount}></IPhone> <!-- vendor未指定 ...(4a)-->
<Android vendor="OPPO" model="Reno11 A"
 count={androidCount}></Android>
<Chromebook vendor="Lenovo" model="IdeaPad Slim 3"
 count={chromebookCount}></Chromebook>

 <script>部の(1)で子コンポーネントをインポートします。コンポーネント名は先頭が大文字になる決まりなので、iPhoneについては「IPhone」というコンポーネント名にしています。マークアップ部の(4)では各コンポーネントにプロパティを指定して記述します。(4a)でvendorが未指定になっていますが、この場合はリスト5(1)で定義したvendorの初期値「Apple」がそのまま利用されます。

 なお、コンポーネントのプロパティには固定値ではなく変数を指定することもできます。リスト6では(2)で定義した在庫数の変数を、(4)で各コンポーネントのcountプロパティに指定しています。(3)はクリック時に在庫数を増やすボタンの実装です。

[補足]スタイル指定はそのコンポーネント内のみに適用される

 Svelteコンポーネントのスタイル指定はコンポーネント内のみに適用されます。図6のサンプルでは、iPhone、Android、Chromebookの子コンポーネントで同一のクラス名containerを利用して、異なるスタイルが個別に指定されていますが、各コンポーネントでスタイルが相互干渉することなく表示されます。

次のページ
コンポーネントからイベントを発生

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Webページ用UIフレームワーク「Svelte」の活用連載記事一覧
この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/19910 2024/07/31 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング