83
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

この記事は社内勉強会用に作成したものです。

Svelte

目次

Svelte とは?

特徴

  • Write less code
  • No virtual DOM
  • Truly reactive

Write less code

少ないコード量で書ける

全てのコードにはバグが存在する可能性があります(All code is buggy)。したがって、書かなければいけないコードが多ければ多いほど、アプリケーションがバグだらけになるのは理にかなっています。

重要なのは読みやすさ(Readability is important)
 巧妙なトリックを使って読みやすさを犠牲にしてでもできるだけコードをコンパクトにするべきだ、と主張しているわけではありません。

for (let i = 0; i <= 100; i += 1) {
  if (i % 2 === 0) {
    console.log(`${i} is even`)
  }
}

↓ 読みやすさを犠牲にコード量を減らす

for (let i = 0; i <= 100; i += 1) if (i % 2 === 0) console.log(`${i} is even`)

他のフレームワークとの比較

入力された 2 つの数字の足し算

  • React: 442 文字
import React, { useState } from "react"

export default () => {
  const [a, setA] = useState(1)
  const [b, setB] = useState(2)

  function handleChangeA(event) {
    setA(+event.target.value)
  }

  function handleChangeB(event) {
    setB(+event.target.value)
  }

  return (
    <div>
      <input type="number" value={a} onChange={handleChangeA} />
      <input type="number" value={b} onChange={handleChangeB} />

      <p>
        {a} + {b} = {a + b}
      </p>
    </div>
  )
}
  • Vue: 263 文字
<template>
  <div>
    <input type="number" v-model.number="a" />
    <input type="number" v-model.number="b" />

    <p>{{ a }} + {{ b }} = {{ a + b }}</p>
  </div>
</template>

<script>
export default {
  data: function () {
    return {
      a: 1,
      b: 2,
    }
  },
}
</script>
  • Svelte: 156 文字
  <script>
    let a = 1;
    let b = 2;
  </script>

  <div>
    <input type="number" bind:value={a}>
    <input type="number" bind:value={b}>

    <p>{a} + {b} = {a + b}</p>
  </div>

No virtual DOM

仮想 DOM を使わない

'仮想 DOM は速い'という神話を完全に終わりにしよう

  • DOM

    • HTML や XML 文書の構造を表現するためのインタフェース
    • 開発者ツールで見られる
  • 仮想 DOM

    • ブラウザ上の実際の DOM と同じような構造を持つ JavaScript オブジェクトのツリー
    • 仮想的な DOM の変更内容をもとに実際の DOM を変更する(最小限の更新が可能)
    • React や Vue などで使用されている

Svelte の 差分更新

  • コンパイル時に変更される可能性がある箇所を最適化された JavaScript コードに変換する
  • 変更時には仮想 DOM を使わずに DOM の必要箇所のみを変更できる
    → 差分検出のコストが必要ない
    → 軽くて速い

Truly reactive

真のリアクティブ(特別なコードを書くことなく UI が更新される)

  • React

      const [count, setCount] = useState(0);
    
      function increment() {
          setCount(count + 1);
      }
    
  • Vue

      let count = ref(0);
    
      function increment() {
        count.value += 1;
      }
    
  • Svelte

    let count = 0;
    
    function increment() {
        count += 1;
    }
    

Svelteの始め方

ローカル

  npm create svelte@latest myapp
  cd myapp
  npm install
  npm run dev

オンラインコードエディタ

svelte REPL

記述方法

チュートリアルが充実している。

Hello world

<script>
  let name = 'world';
</script>

<h1>Hello {name}!</h1>

省略記法

  <img src={src} alt="A man dances.">

  <img {src} alt="A man dances.">

リアクティビティ

  • 値を変更するだけで画面に反映される
  function incrementCount() {
    count += 1;
  }

リアクティブ宣言

  • 変数と変数を同期させる

      // countが変更されるとdoubledも変更される
      let count = 0;
      $: doubled = count * 2;
    
  • ステートメントを同期させる

      $: console.log('the count is ' + count);
    
  • ブロック

      $: {
        console.log('the count is ' + count);
        alert('I SAID THE COUNT IS ' + count);
      }
    
  • if 文

      $: if (count >= 10) {
        alert('count is dangerously high!');
        count = 9;
      }
    

配列やオブジェクトの場合

大まかなまとめ: 更新される変数は代入の左側に直接置かなければならない。

  • 自身を代入する

      function addNumber() {
        numbers.push(numbers.length + 1);
        numbers = numbers;
      }
    
  • スプレッド構文を使う

      function addNumber() {
        numbers = [...numbers, numbers.length + 1];
      }
    

HTML内のロジック

分岐や繰り返しなどのロジックは{}を用いる

# の文字は常に ブロックの開始 タグを示します。
/ の文字は常に ブロックの終了 タグを示します。
: の文字は {:else} のように ブロックの継続 タグを示します。

if 文

  {#if x > 10}
    <p>{x} is greater than 10</p>
  {:else if 5 > x}
    <p>{x} is less than 5</p>
  {:else}
    <p>{x} is between 5 and 10</p>
  {/if}

each 文

第二引数として index を取得できる

  <ul>
    {#each cats as cat, i}
      <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}" rel="noreferrer">
        {i + 1}: {cat.name}
      </a></li>
    {/each}
  </ul>

await

非同期処理によって処理の終了を待つ

  {#await promise}
    <p>...waiting</p>
  {:then number}
    <p>The number is {number}</p>
  {:catch error}
    <p style="color: red">{error.message}</p>
  {/await}
83
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?