Open370

実践 Svelte 入門

hagiwarahagiwara
hagiwarahagiwara

1.1.1 Svelte の特徴

hagiwarahagiwara
  • 状態管理
    • 変数を定義し、新しい値を代入するだけ
    • 「普通の」HTML、JS
      • JS
        • 変数定義、値の代入
      • HTML
        • 変数
          • {hoge}
        • 制御構文
          • {#if}, etc
        • イベントハンドラ
          • on:click={ ... }, etc
hagiwarahagiwara

1.1.2 Svelte における「コンパイル」

hagiwarahagiwara
  • Svelte で書かれたコンポーネントはそのままブラウザに読み込まれない
  • ランタイムなしで実行可能な形に変換されて読み込まれる
hagiwarahagiwara

1.1.3 仮想 DOM を使わない

hagiwarahagiwara
  • 複雑化したフロントエンドの DOM 構造を適切に把握することは人間には難しい
    • 仮想 DOM
      • React
    • コンパイル時に解決
      • Svelte
hagiwarahagiwara

1.2.2 HTML/CSS による画面構成要素の作成

hagiwarahagiwara

App.svelte なんかエラー出てる

Error in svelte.config.js

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@sveltejs/vite-plugin-svelte' imported from /svelte-book-first-tutorial/svelte.config.js

hagiwarahagiwara
  • Svelte の構文は普通の HTML / CSS に近い
    • 導入の強い後押しになる
hagiwarahagiwara

1.2.3 変数とイベントハンドラによる「カートに入れる」ボタンの挙動作成

hagiwarahagiwara
  • 状態(ステート)
    • 変数を使って表現
    • Svelte は変数への代入を特別扱いする
      • 変数への代入によって状態変化を認識する
        • 変数に代入しないと伝わらない
          • 画面が更新されない
      • 開発者体験をシンプルにするため
        • 「代入文を書くとリアクティブになる」
hagiwarahagiwara

1.2.5 コンポーネントの分割

hagiwarahagiwara
  • 画像スライダーをコンポーネントに分割
  • コンポーネント
    • 1 svelte ファイル = 1コンポーネント
    • 管理する範囲を限定する
      • 変更やテストが容易になる
      • 変数名や関数名を簡単な名前に変えられる
  • プロパティ
    • コンポーネントの外部から値を設定できる
      • 例)画像に関する情報を親コンポーネントから渡してもらう
    • プロパティの定義
      • export let hoge
    • プロパティの指定は HTML の属性と同様
      • <Slider hoge={...} />
  • リアクティブステートメント
    • $: ...
    • 依存関係にある別の状態に応じて状態を更新する
      • 例)B, C の値が変わると A の値も変わる
        • $: A = B + C
    • コードが簡単になりバグも入りにくくなる
hagiwarahagiwara

2.1 環境構築

hagiwarahagiwara

Vite

$ npm create vite@latest project-name -- --template svelte
$ cd project-name
$ npm install
$ npm run dev -- --open
hagiwarahagiwara

Vite (TS の場合)

$ npm create vite@latest project-name -- --template svelte-ts
hagiwarahagiwara


(書籍から引用)

  • src/
    • .js, .svelte など、アプリケーションのコード
      • 必要に応じてコンパイルされる
  • public/
    • サーバからそのまま配信される
  • vite.config.js
    • Vite の設定ファイル
hagiwarahagiwara

2.2.1 .svelte ファイルの構造

hagiwarahagiwara
  • コンポーネント
    • コンポーネント内の関心事に集中できる
      • 他のコンポーネントに影響しない
    • 再利用しやすくなる
  • Svelte コンポーネント
    • .svelte ファイル
      • HTML, JS, CSS をまとめて記述
        • <script> ブロック(省略可)
        • <style> ブロック(省略可)
        • テンプレート(上記以外)
hagiwarahagiwara

2.2.3 スタイル

hagiwarahagiwara
  • <style> ブロック
    • スコープ化される
      • 他のコンポーネントに影響しない
    • :global 修飾子
      • :global(body) { ... }
      • スコープ化を無効にする
        • 全体に適用したい場合に使う
  • class 属性の省略記法
    • 例) class={active ? 'active' : ''}
      • class:active={active}
      • class:active (変数名とクラス名が同じ場合)
      • class="button" class:blue={theme==='blue'} class:disabled (複数・併用可)
  • style 属性の省略記法
    • style="color: red" (通常)
    • style:color="red"
    • style:color={color} (値が変数の場合)
    • style:color (プロパティ名と変数名が同じ場合)
    • (複数・併用可)
hagiwarahagiwara

2.2.6 プロパティ

hagiwarahagiwara
  • プロパティ
    • コンポーネントの動的な部分を指定する
      • 例)ボタンのラベル、有効・無効の指定、など
    • プロパティを作成する
      • 子コンポーネント(プロパティを渡される側)
      • export let hoge
    • プロパティに値を渡す
      • 親コンポーネント
      • <Component hoge={値} />
        • 「2.2.2 テンプレートの基本的な記法」と同じ記法が使用できる
        • {...$$props}
          • 親コンポーネントから渡された全てのプロパティが格納される
        • {...$$restProps}
          • 親コンポーネントから受け取ったプロパティのうち、export let で明示的に宣言したプロパティ以外のプロパティが格納される
hagiwarahagiwara

2.2.7 スロット

hagiwarahagiwara
  • スロット
    • <slot />
    • 子テンプレートで使用する
      • 親コンポーネントからコンテンツを自由に挿入できる
    • フォールバックコンテンツ
      • スロットにコンテンツが挿入されなかった場合にデフォルトで表示する内容
      • <slot>フォールバックコンテンツ</slot>
  • 名前付きスロット
    • コンポーネントに複数のスロットを設ける場合、名前を付けて区別できる
    • 通常の(名前のない)スロットとも併用可
    • 子コンポーネント
      • slotname 属性を付与する
      • <slot name="hoge" /> ... <slot />
    • 親コンポーネント
      • 名前付きスロットに挿入したい要素に slot 属性を付与する
        • slot 属性の付与されてない要素は全て名前のないスロットに挿入される
      • <Component><div slot="hoge"> ... </div><div> ... </div</Component>
hagiwarahagiwara
  • <svelte:fragment>
    • スロットに挿入するコンテンツを div 等の HTML 要素で囲みたくない場合に使用する
    • <Component><svelte:fragment slot="hoge"> ... </svelte:fragment></Component>
  • $$slots
    • コンポーネントで定義したスロットの名前がキーになったオブジェクトが格納された特別な変数
    • 親コンポーネントから特定のスロットにコンテンツが挿入されているかの判断に使用できる
      • {#if $$slot.title} ... {/if}
        • title スロットにコンテンツが挿入されている場合、true になる
  • スロットプロパティ
    • スロットに挿入されたコンテンツに子コンポーネントから値を渡す場合に使用する
    • 子コンポーネント
      • <slot プロパティ名={値} />
    • 親コンポーネント
      • <Component let:プロパティ名={変数}> {変数} </Component>
        • 変数にスロットで指定した値が入る
        • プロパティ名は slot と合わせる
        • 変数名は自由
      • 名前付きスロットから値を渡される場合、let:〜 はコンポーネントではなく slot 属性を付与した要素に追加する
        • <Component><div slot="hoge" let:プロパティ名={変数}> {変数} </div></Component>
    • 省略記法
      • <slot {hoge} />
        • <slot hoge={hoge} /> と同じ
      • <Component let:{hoge}
        • <Component let:hoge={hoge} と同じ
hagiwarahagiwara

COLUMN スロットを使うべきか、プロパティを使うべきか

  • スロット
    • 内容を自由に指定したい場合
  • プロパティ
    • 内容をある程度固定したい場合
hagiwarahagiwara

2.2.8 イベント

hagiwarahagiwara
  • DOM イベント
    • on:イベント名={関数}
      • <button on:click={handleClick}> ... </button>
      • <button on:click={() => alert('hoge')}> ... </button>
  • イベント修飾子
    • 慣例的によく行われる処理を指定できる記法
      • on:イベント名| でつなぐ
        • <button on:click|preventDefault={handleClick> ... </button>
      • 複数指定可
    • 修飾子
      • preventDefault
      • stopPropagation
      • passive
      • nonpassive
      • capture
      • once
      • self
      • trusted
  • コンポーネントイベント
    • DOM イベントとは別に、コンポーネント独自のイベントを発生させる
    • createEventDispatcher()
  • イベント転送
    • 子コンポーネントのイベントを親コンポーネントにそのまま転送する
      • 親コンポーネントでイベントハンドラを指定する
hagiwarahagiwara

2.2.9 ライフサイクル

hagiwarahagiwara

コード 2.2.49

let contents = Array.from({ length: 100 }, (_, i) => `投稿 ${i}`);

_ は、Array.from() メソッドのコールバック関数で配列の要素の値(i はインデックス)が入るところだけど、

アンダースコア _ 自体は特別な意味は持たないが、コード内で値を無視することや、意図的に無名の変数またはパラメータを示すためによく使用される慣習

らしい
へー

_ の使用法は言語やコミュニティによって異なります。_ を無視される変数として使用する慣習は、可読性やコードの意図を明確にするためのツールとして広まってきました。ただし、コーディング規約やチームの合意に従うことが重要です。

hagiwarahagiwara
  • ライフサイクル
    • ブラウザ上で実行される際の処理の流れ
  • ライフサイクル関数
    • onMount
      • コンポーネントの初回レンダリングが完了した直後
    • onDestroy
      • コンポーネントが削除される直前
    • beforeUpdate
      • DOM が更新される直前
    • afterUpdate
      • DOM が更新された直後
    • tick
      • 状態の変更が DOM に反映するまで待機する
  • 処理実行のタイミング
    • マウント時
      1. コンポーネントのマウント
      2. <script> ブロックの実行
      3. beforeUpdate
      4. DOM 要素のレンダリング
      5. onMount
      6. afterUpdate
    • 内部状態の更新時
      1. 内部状態の更新
      2. beforeUpdate
      3. DOM 要素のレンダリング
      4. afterUpdate
      5. tick の解決
    • アンマウント時
      1. コンポーネントのアンマウント
      2. onDestroy
hagiwarahagiwara

第3章 Svelte のリアクティビティ

hagiwarahagiwara
  • リアクティビティ
    • データ(状態)と UI が同期して更新される性質
hagiwarahagiwara

3.1.1 変数代入

hagiwarahagiwara
  • 変数代入
    • 変数への代入を内部状態の変更とみなし、DOM 構造へ自動的に反映する
<script>
  let count = 0
</script>

<button on:click={() => count = count +1}> {count} </button>
<!-- count +=1 でも可 -->
hagiwarahagiwara

3.1.2 $: プレフィックス

hagiwarahagiwara
  • $: 記法
    • 変数の変更に応じて別の変数も自動で更新される
    • 複数の文を記述する場合 { } で囲う
      • $: { ... }
    • 関数呼び出しも可
      • $: console.log(...)
    • 条件を満たした場合のみ実行する
      • $: if (hoge) { ... }
hagiwarahagiwara

3.1.3 配列とオブジェクトの更新

hagiwarahagiwara
  • 配列
    • 配列の要素を変更する関数を使用する場合、自動で更新されない
      • push, pop, splice, sort, など
      • 変数への代入を追加する
  • オブジェクト
    • オブジェクトのプロパティへの代入は変数と同様に扱われる
      • 代入の左辺にオブジェクトの変数が直接現れる場合のみ
hagiwarahagiwara

3.1.4 入力のバインディング

(ユーザー入力を扱う要素の属性に対するバインディング)

hagiwarahagiwara
  • テキスト
  • 数値
  • チェックボックス
  • ラジオボタン
  • セレクトボックス
  • グループ
hagiwarahagiwara
  • バインディング
    • DOM 要素の属性値の更新を、コンポーネントの変数にも自動で反映する
      • bind:属性
        • <input type="text" bind:value={hoge}>
        • <input type="checkbox" bind:checked={isChecked}>
    • グループ
      • 複数の要素をグループ化して1つの変数にバインドする
        • ラジオボタンやチェックボックスなど
          • チェックボックスは複数選択可能なため変数は配列になる
      • bind:group={hoge}
        • <input type="radio" bind:gourp={hoge} value="...">
        • <input type="checkbox" bind:gourp={hoges} value="...">
    • セレクト
      • <option> の値が <select>value 属性にバインドした変数に代入される
        • <select bind:value={hoge}><option value="...">〜</select>
      • multiple の場合、複数選択可能なので変数は配列になる
        • <select multiple bind:value={hoges}><option value="...">〜</select>
hagiwarahagiwara

3.1.5 メディア要素のバインディング

(メディアを扱う要素の属性に対するバインディング)

hagiwarahagiwara
  • メディア要素のバインディング
    • <video>, <audio>
      • 動画や音声の再生をコントロールする UI を操作した結果が変数に反映される
        • <video ... bind:currentTime={time}>
    • 双方向
      • currentTime
      • playbackRate
      • paused
      • volume
      • muted
    • read only
      • duration
      • buffered
      • played
      • seekable
      • seeking
      • ended
      • readyState
      • videoWidth (video のみ)
      • videoHeight (video のみ)

hagiwarahagiwara

3.1.6 コンポーネントバインディング

(コンポーネントのプロパティに対するバインディング)

hagiwarahagiwara
  • コンポーネントバインディング
    • DOM 要素と同様にコンポーネントのプロパティに対してもバインディング可
hagiwarahagiwara

3.1.7 this バインディング

hagiwarahagiwara
  • DOM 要素に対するバインディング
  • Svelte コンポーネントに対するバインディング
hagiwarahagiwara
  • this バインディング
    • DOM 要素
      • 属性ではなく、DOM 要素自体を変数にバインディングする
      • テンプレート内の DOM 要素を簡単に取得できる
      • bind:this={変数}
        • <canvas bind:this={hoge} ... />
          • 変数 hoge から Canvas API を呼び出せる
    • コンポーネント
      • コンポーネントも同様にバインディング可能
      • コンポーネント内で export した const, class, function にアクセスできる
        • <Component bind:this={hoge} />
hagiwarahagiwara

3.2 ストア

hagiwarahagiwara
  • writable ストア
  • readable ストア
  • derived ストア
  • カスタムストア
hagiwarahagiwara
  • ストア
    • 複数のコンポーネントで状態を共有するための仕組み
      • 変数は単一コンポーネント内のみ
    • writable ストア
      • 参照・更新の両方可
    • readable ストア
      • 参照のみ可
    • derived ストア
      • 他のストアの値に応じて値が変化する
    • カスタムストア
      • Svelte が提供する関数以外で作成されたストア
hagiwarahagiwara

3.2.1 writable ストア

hagiwarahagiwara
  • writable ストア
    • 値の参照・更新の両方可
      • 例)複数コンポーネントでログイン状態を真偽値として共有する
        • export const isLogin = writable(false)
    • 操作
      • set(val)
        • ストアの値を val に設定する
      • subscribe(callback)
        • ストアを購読する
          • ストアの値が変化した際、変化後の値を引数に callback が実行される
        • 購読を解除する関数を戻り値として返す
      • update(updater)
        • ストアの値を更新する
          • 現在の値を引数に updater が実行される
            • 戻り値を新しい値としてストアに設定する
hagiwarahagiwara

3.2.2 $ による自動購読

hagiwarahagiwara
  • $ による自動購読
    • $ストア名
      • {#if $isLogin} ... {/if}
    • ストアの最新の値を参照できる
      • ストアの値を受け取る変数、購読解除の手続きが不要
hagiwarahagiwara

3.2.2 $ による代入

hagiwarahagiwara
  • $ による代入
    • $ストア名 = hoge
      • $isLogin = true
    • ストアの値を更新できる
      • set() を使用するより直感的
hagiwarahagiwara

3.2.5 derived ストア

hagiwarahagiwara
  • derived ストア
    • 他のストアの値に応じて値が変化するストア
hagiwarahagiwara

3.2.6 カスタムストア

hagiwarahagiwara
  • カスタムストア
    • 自前で作成したストア
      • サードパーティの状態管理ライブラリと組み合わせて使用する場合
      • svelte/store で作成したストアに固有のインターフェースを持たせたい場合
    • 要件
      • subscribe メソッド
      • set メソッド
      • 画像スライダー
hagiwarahagiwara

3.2.7 ストアのバインディング

hagiwarahagiwara
  • ストアのバインディング
    • writable ストア、set メソッドを持ったカスタムストアは、 「3.1 コンポーネントのリアクティビティ」で説明した各種バインディングの対象として指定できる
    • <input ... bind:value={$store}>
      • 自動購読と同様、ストア名の先頭に $ をつける
hagiwarahagiwara

4.1.1 キー付きの {#each} ブロック

hagiwarahagiwara
  • キー付きの {#each} ブロック
    • 繰り返しの各要素を厳密に区別するための記法
      • {#each 配列 as 変数 (キー)}
      • {#each 配列 as 変数, インデックス (キー)}
    • キーは配列中の要素を一意に区別できるものを指定する
      • 判定が容易な文字列 or 数値を推奨
hagiwarahagiwara

4.1.2 {#key} ブロック

hagiwarahagiwara
  • {#key} ブロック
    • 指定した式の値が変更されると、内包するコンテンツを破棄・再生成する
    • {#key value} <Component /> {/key}
      • value の値が変わる度に <Component /> が作成・レンダリングされる
    • {#key value} <div transitoin:fade> ... </div> {/key}
      • value の値が変わる度にトランジションが再生される
hagiwarahagiwara

4.1.3 {@...} タグ

hagiwarahagiwara
  • {@ ...} タグ
    • ブロックとは異なり {@ ...} だけで完結する
    • {@html 式}
      • {@html '<strong> 強調したテキストを出力する </strong>}`
      • 式の内容を HTML として出力する
        • < > などがエスケープされない
        • HTML として正しくないと動作しない
      • ユーザー入力などをそのまま出力すると XSS 脆弱性を生じるので注意する
    • {@debug 変数}
      • {@debug hoge} {@debug hoge, foo, bar}
        • 変数の値が変化すると、その値をログに出力する
          • console.log(...) の代わりになる
          • ブラウザの開発者ツールを開いている場合、コードの実行を一時停止する
        • 変数を複数指定可
        • 変数以外は指定できない
      • {@debug}
        • 変数を指定しない場合、debugger 文が挿入される
          • いずれかの状態が変化するとトリガーされる
    • {@const 変数 = 式}
      • 一時的な変数を定義する
      • {#if}, {:else if}, {:else}, {#each}, {:then}, {:catch}, <Component>, <svelte:fragment> の直下にのみ配置できる
hagiwarahagiwara

4.1.4 <svelte:...> タグ

hagiwarahagiwara
  • <svelte:self>
  • <svelte:component>
  • <svelte:element>
  • <svelte:window>
  • <svelte:body>
  • <svelte:head>
  • <svelte:options>
  • <svelte:fragment>
hagiwarahagiwara
  • <svelte:self>
    • コンポーネント自身を表示するタグ
    • このタグを書いた箇所にコンポーネント自身が表示される
      • 無限ループを防ぐため {#if}, {#each} ブロックの内側に入れる
      • または、コンポーネントのスロットに渡す
  • <svelte:component>
    • コンポーネントを動的に表示するタグ
    • <svelte.component this={Component} hoo={bar} />
      • this プロパティに表示するコンポーネントの変数を渡す
        • this の値が false の場合、何もレンダリングされない
  • <svelte:element>
    • DOM 要素を動的に表示するタグ
    • <svelte:element this={'div'} attr={val}> ... </svelte:element>
      <svelte:element this={\h${level}`}> ... </svelte:element>`
      • this プロパティに表示する HTML 要素名を渡す
        • this の値が false、存在しない要素名の場合、何もレンダリングされない
        • this の値が hr, br, 等の場合、子要素を持たせるとエラーになる
      • 属性値を付与したい場合、<svelte:element> に直接記載する
      • バインディングは bind:this のみ使用可
  • <svelte:window>
    • Window オブジェクトにイベントハンドラを設定する、一部のプロパティをバインディングするためのタグ
      • コンポーネントが破棄される際、イベントハンドラも Window オブジェクトから自動的に削除される
        • イベントハンドラを削除するコードが必要ない
    • <svelte:window on:keydown={func} />
    • <svelte:window bind:scrollY={val} />
      • バインドできるプロパティ
        • innerWidth, innerHeight, outerWidth, outerHeight, scrollX, scrollY, online
  • <svelte:body>
    • document.body オブジェクトにイベントハンドラを設定するためのタグ
      • バインディングできるプロパティは無し
    • <svelte:body on:mouseenter={func} on:mouseleave={func} />
  • <svelte:head>
    • <head> タグ内のコンテンツを指定するタグ
    • <svelte:head> <title>...</title><meta ... /> </svelte:head>
  • <svelte:options>
  • <svelte:fragment>
    • スロットに挿入するコンテンツを div 等の HTML 要素で囲みたくない場合に使用する
    • <svelte:fragment slot="hoge"> ... </svelte:fragment>
hagiwarahagiwara

4.2 モジュールコンテキスト

hagiwarahagiwara
  • モジュールコンテキスト
    • 通常、<script> ブロック内の処理はコンポーネントのインスタンスが生成される度に実行される
    • <script>context="module" を追加すると、そのブロックはモジュールコンテキストとなる
      • モジュールにつき1回だけ実行されるようになる
    • 用途
      • コンポーネントのインスタンス間で状態を共有する場合
      • コンポーネント本体以外にエクスポートしたいものがある場合
hagiwarahagiwara

4.2.1 各インスタンス間での状態の共有

hagiwarahagiwara
  • 各インスタンス間での状態の共有
    • モジュールコンテキストの <script> ブロックは1回しか実行されない
      • 同じコンポーネントのインスタンス間で共有できる単一の変数を定義できる
      • 複数のビデオが並んでいる UI
        • ビデオを再生した際に、他のビデオの再生を停止する
        • ビデオコンポーネントのモジュールコンテキストで「現在再生中の video 要素」の変数を定義し、インスタンス間で共有する
hagiwarahagiwara

4.2.2 コンポーネント以外のエクスポート

hagiwarahagiwara
  • コンポーネント以外のエクスポート
    • モジュールコンテキストでエクスポートした変数や関数を他のコードからインポートできる
    • .js ファイルからインポートする方法と同様
      • import { hoge } from './Hoge.svelte
    • export default は不可
      • .svelte ファイルのデフォルトエクスポートはコンポーネント本体
hagiwarahagiwara

4.3 モーション・トランジション・アニメーション

hagiwarahagiwara
  • DOM 要素の動きを制御するの3つの方法
    • モーション
      • 数値が滑らかに変化するストアを提供する
    • トランジション
      • 要素が表示・非表示する際の動きを指定する
    • アニメーション
      • 要素が入れ替わる際の動きを指定する
hagiwarahagiwara

4.3.1 モーション

hagiwarahagiwara
  • tweened
    • delay オプション
    • duration オプション
    • easing オプション
    • interpolate オプション
  • spring
    • stiffness オプション
    • damping オプション
    • precision オプション
hagiwarahagiwara
  • モーション
    • 数値が滑らかに変化するストア
      • 時間をかけて徐々に値が変化する
        • CSS アニメーション
    • ストアを作成する関数
      • svelte/motion からインポートする
      • 2つの関数
        • tweened, spring
      • tweened
        • 値が一定の時間をかけて変化する
        • 値が徐々に変化する以外は通常の writable ストアと同様
        • 指定できるオプション
          • delay, duration, easing, interpolate
      • spring
        • 値がバネの動きのように変化する
        • 指定できるオプション
          • stiffness, damping, precision
hagiwarahagiwara

4.3.2 トランジション

hagiwarahagiwara
  • ディレクティブ
    • transition:
    • in:
    • out:
  • 関数
    • fade
    • blur
    • fly
    • slide
    • scale
    • crossfade
hagiwarahagiwara
  • トランジション
    • コンポーネントの状態(変数)の変化によって DOM 要素が表示・非表示する際、その動きをカスタマイズする仕組み
        • フェードイン、フェードアウト
    • transision: ディレクティブ
      • <div transition:関数> ... </div>
      • 表示・非表示の仕方を定義する関数を指定する
      • パラメータの指定可
        • <div transition:関数={パラメータ(オブジェクト)}> ... </div>
          • ディレクティブに指定した関数の第2引数に渡される
        • <div transition:fade={{ duration: 1000 }}>
    • in:, out: トランジション
      • <div in:関数 out:関数> ... </div>
      • 表示・非表示の仕方を別々に指定する場合
        • 片方だけの指定可
        • 指定する関数が同じ場合は transition: を使用する方が良い
    • 関数
      • svelte/transition
        • fade, blur, fly, slide, scale, draw, crossfade
      • 独自関数
hagiwarahagiwara

4.3.2 アニメーション

hagiwarahagiwara
  • アニメーション
    • ブロック内の要素の位置が変わる際の動き(アニメーション)をカスタマイズする仕組み
      • 要素の追加・削除では動作しない
    • キー付き {#each} ブロック内でのみ使用可
    • animate: ディレクティブ
      • <div animate:関数> ... </div>
      • {#each} の直下のみ有効
      • アニメーションの挙動を定義する関数を指定する
      • パラメータの指定可
        • <div animate:関数={パラメータ(オブジェクト)}> ... </div>
    • 関数
      • svelte/animate
        • flip
      • 独自関数
hagiwarahagiwara

4.4 コンテキスト

hagiwarahagiwara
  • コンテキスト
    • ストアとは別の、コンポーネント間でデータを共有する仕組み
hagiwarahagiwara

4.4.1 コンテキスト API の使い方

hagiwarahagiwara
  • コンポーネント
    • 親コンポーネントから子コンポーネントに対してデータを共有する仕組み
      • 一種のキーバリューストアと想定可
    • コンテキスト API
      • setContext(親), getContext(子)
      • コンポーネントの初期化時に呼び出す必要がある
        • 任意の箇所で値を読み書きできない
          • 例)onMount、イベントハンドラ
    • 例)
      • <canvas> の2Dコンテキストをコンポーネント間で共有する
hagiwarahagiwara

4.4.2 コンテキストの特徴とストアとの比較

hagiwarahagiwara
  • コンテキストの特徴
    • 任意のコンポーネント間でデータのやりとりができない
      • 先祖・子孫間のみ可
    • リアクティブではない
      • コンテキストの値を変更してもコンポーネントは再レンダリングされない
    • コンポーネントのインスタンス毎に別々の値を保持する
  • ストアとの比較
    • コンテキスト
      • 親子関係が定まっているコンポーネント間でデータを共有する場合
    • ストア
      • 親子関係が定まっていないコンポーネント間でデータを共有する場合
      • リアクティブ性が必要な場合
hagiwarahagiwara

4.5 アクション

hagiwarahagiwara
  • アクション
    • DOM 要素に Svelte コンポーネントのようなライフサイクル管理の仕組みを提供する
    • DOM 要素が作成された際に呼び出される関数
hagiwarahagiwara

4.5.1 アクションの基本的な使い方

hagiwarahagiwara
  • アクション(関数)の定義
    • 第1引数に DOM 要素、第2引数にパラメータ
    • 戻り値に update, destroy をキーに持つオブジェクト
      • どちらも省略可
      • update
        • パラメータが更新された際に呼び出される関数
      • destroy
        • DOM 要素 が削除された際に呼び出される関数
  • 使い方
    • use: ディレクティブ
      • <div use:関数={パラメータ}> ... </div>
hagiwarahagiwara

第5章 SvelteKit による複数ページアプリケーションの開発

hagiwarahagiwara

5.1.1 SvelteKit とは

hagiwarahagiwara
  • Svelte
    • UI を構築するためのライブラリ
  • SvelteKit
    • UI 以外の部分を提供するフレームワーク
hagiwarahagiwara

5.1.3 SvelteKit プロジェクトのファイル構造

hagiwarahagiwara
  • 重要なファイル、フォルダ
    • src/
      • routes/
        • サーバールート
          • ファイルベースのルーティング
      • lib/
        • ライブラリ
        • import hoge $lib/hoge.js
      • static/
        • 静的ファイル
    • svelte.config.js
    • vite.config.js
    • .svelte-kit
    • package.json
  • ファイルベースのルーティング
hagiwarahagiwara

5.2.2 レイアウト ー 複数ページに共通の要素を配置

hagiwarahagiwara

5.2.3 フォームアクション ー プログレッシブな Web アプリケーションを構築する仕組み

hagiwarahagiwara

参考)

オプショナルチェーン (?.) - JavaScript | MDN

?. 演算子の機能は . チェーン演算子と似ていますが、参照が nullish (null または undefined) の場合にエラーとなるのではなく、式が短絡され undefined が返されるところが異なります。

?. を . の代わりに用いることで、 JavaScript が obj.first.second にアクセスしようとする前に obj.first が null または undefined でないことを暗黙的に確かめるようになります。obj.first が null または undefined であった場合、式が自動的に短絡され、 undefined が返ります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining


Null 合体演算子 (??) - JavaScript | MDN

Null 合体演算子 (??) は論理演算子の一種です。この演算子は左辺が null または undefined の場合に右の値を返し、それ以外の場合に左の値を返します。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

hagiwarahagiwara

Null 合体演算子と共に使う
Null 合体演算子はオプショナルチェーンの後につけることで、値が存在しなかったときの既定値を指定することができます。

let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city

オプショナルチェーン (?.) - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining

hagiwarahagiwara

5.3.4 ④ フォームアクションでのカートへの追加

hagiwarahagiwara

カートの情報を保存する data/cart.json ファイルは存在するが内容が空(JSON データとして不完全)の場合、エラーになる

SyntaxError: Unexpected end of JSON input

(内容だけ削除しないでファイルごと削除する or 空の配列 [] を入れておく)

hagiwarahagiwara

5.3.5 ⑤ 「おすすめ商品」の表示

hagiwarahagiwara

参考)

Snapshots • Docs • SvelteKit

サイドバーのスクロールポジションや、<input> 要素の中身などの、一時的な DOM の状態(state)は、あるページから別のページに移動するときに破棄されます。

例えば、ユーザーがフォームに入力し、それを送信する前にリンクをクリックして、それからブラウザの戻るボタンを押した場合、フォームに入力されていた値は失われます。入力内容を保持しておくことが重要な場合、DOM の状態を スナップショット(snapshot) として記録することができ、ユーザーが戻ってきたときに復元することができます

https://kit.svelte.jp/docs/snapshots

hagiwarahagiwara

6.8.2 $app/forms - フォームアクションに関するヘルパー

hagiwarahagiwara

6.8.5 $app/stores - アプリケーションレベルのストア

hagiwarahagiwara

ハイドレーションとは?

hagiwarahagiwara

参考)

Time to interactive (対話までの時間) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN

TTI は 2018 年に Web Incubator Community Group によって提案されたもので、ページまたはアプリケーションに有用なコンテンツが含まれ、メインスレッドがアイドル状態になり、イベントハンドラーの登録など、ユーザーの操作に自由に応答できるようになるメトリクスを提供します。

https://developer.mozilla.org/ja/docs/Glossary/Time_to_interactive


Resumable - Qwik

Resumability is about pausing execution in the server and resuming execution in the client without having to replay and download all of the application logic.

A good mental model is that Qwik applications at any point in their lifecycle can be serialized and moved to a different VM instance (server to browser). There, the application simply resumes where the serialization stopped. No hydration is required. This is why we say that Qwik applications don't hydrate; they resume.

https://qwik.builder.io/docs/concepts/resumable/

hagiwarahagiwara

6.8.7 $env - 環境変数へのアクセスを提供するモジュール

hagiwarahagiwara

6.9.1 設定が不要なホスティングサービス - adapter-auto

hagiwarahagiwara

7.2.4 カートを MongoDB で実装

hagiwarahagiwara

MongoTopologyClosedError: Topology is closed

接続できないな?と思ったら .env のプロパティ名が間違ってた

hagiwarahagiwara

第8章 Auth0 によるパスワードレスログイン実装とセッション管理

hagiwarahagiwara

8.2.6 ログインの動作確認

hagiwarahagiwara

コールバックでなんかエラー

You've reached the maximum number of attempts. Please try to login again.

hagiwarahagiwara

セッションを作成する関数の export 抜けてた ><

修正して無事ログインできた模様

hagiwarahagiwara

8.4.1 ユーザーIDごとにカートを作成

hagiwarahagiwara

todo)

  • カート画面 /cart の修正もする
    • 500 エラー
    • 商品情報が表示されない

商品詳細ページの関数呼び出し、ボタン処理の変更に習って修正で done

hagiwarahagiwara

8.5 Vercel へのデプロイ

hagiwarahagiwara

参考)

adapter-vercel
Vercel • Docs • SvelteKit https://kit.svelte.jp/docs/adapter-vercel

Deploy Status > Building のログに出る ↓

If you plan on staying on this deployment platform, consider replacing @sveltejs/adapter-auto with @sveltejs/adapter-vercel. This will give you faster and more robust installs, and more control over deployment configuration.

hagiwarahagiwara

COLUMN 最新情報の取得方法

hagiwarahagiwara
hagiwarahagiwara

第9章 ユーザー体験の改善 - OGP タグとプリレンダリング

hagiwarahagiwara

9.2.3 カート情報のクライアントサイドでの読み込み

hagiwarahagiwara

参考文献

hagiwarahagiwara
hagiwarahagiwara

序文

hagiwarahagiwara
  • Svelte
    • シンプル
    • 事前コンパイル
    • モバイルファースト時代にあるべき UI フレームワーク
  • SvelteKit
    • シンプル
    • Svelte と同じチームが開発
  • 本書
    • 機能の背景、実際の応用例
    • 概要を理解してから詳細を理解する
    • Web の情報では得られない速度、深度で Svelte を理解する
hagiwarahagiwara

はじめに

hagiwarahagiwara
  • Svelte / SvelteKit の解説書
    • チュートリアル(概要)
    • 詳細説明
  • 前半
    • Svelte
      • 基本的な概念
      • プロジェクトのセットアップ方法
      • 機能の解説
  • 後半
    • SvelteKit
      • サンプルプロジェクト
      • Web アプリケーションの開発方法