Vue使いなら秒で覚えられるSvelte入門

#Svelteって何？

速くていい感じの JS フレームワークです。
詳しい説明は[こちらの記事](https://qiita.com/so99ynoodles/items/a8144ced1a21467c6300)をご参照ください。

当記事では Svelte の基本的な文法を Vue と比較しながら解説していきます。

#Vueとの比較
以下では Vue の構成要素ごとに、Svelteではどう書けるかを解説します。
コードは全て[プレイグラウンド](https://svelte.dev/repl/hello-world?version=3.4.2)でサクッと試すことができます。
（Svelteのバージョン：v3.4.2）

###data
Vueで言うところの`data`はそのまま変数として宣言すればいいだけです。

HTML内で表示するには波カッコ1つで囲みます。

```HTML
<h1>Hello { name }</h1>

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

これで'Hello world'と表示されます。

またVueと同様に波カッコの中には JS 文を書くことができます。

```HTML
<h1>Hello { name.toUpperCase() }</h1>
<!-- Hello WORLD と表示される -->

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

###v-bind
単方向バインドも波カッコで囲んだ中に入れるだけです。

```HTML
<input type="text" value="{value}">

<script>
  let value = 'world';
</script>
```

また、属性名と変数名が等しい場合は次のような略記も可能です。

```HTML
<input type="text" {value}>

<script>
  let value = 'world';
</script>
```

###v-model

ここが Vue ユーザにとっては少し紛らわしいのですが、
双方向バインディングの場合は属性に`bind:`を付けます。

```HTML
<input type="text" bind:value="{value}">

<script>
  let value = 'world';
</script>
```

###methods

`data`に当たるものが普通の変数なので`methods`も普通の関数の形で書けます。

クリックイベントにバインドするには`on:click`ディレクティブを用います。
他のイベントも同様です。
  
```HTML
<button on:click="{handleClick}">ボタン</button>
<p>
  ボタンは{ count }回押されました。
</p>

<script>
  let count = 0
  const handleClick = () => {
    count += 1
  }
</script>
```

### computed

`computed`に当たるものは少し独特な記法`$:`を用います。
**`$:`の後に書かれた文は、その文の中で参照された変数が変化するたびに再実行されます。**

```javascript
$: computedProp = prop * 2
```

つまり上の例では、`prop`が変化するたびに、`computedProp`に`prop * 2`が代入されるようになっています。

全体の例も置いておきます。
この例では`isEven`が`count`から算出されるようになっています。

```HTML
<button on:click="{handleClick}">ボタン</button>
<p>
  あなたはボタンを{isEven ? '偶数' : '奇数'}回押しています。
</p>

<script>
  let count = 0

  // countが変化するたび再代入される
  $: isEven = count % 2 === 0

  const handleClick = () => {
    count += 1
  }
</script>
```

複数行の処理を書きたい場合は、波括弧で囲んでブロックを作ればOKです。

```javaScript
  let count = 0
  let doubled = 0

  $: {
    console.log(count)
    doubled = count * 2
  }
```

あるいは関数を作ってそこで処理を行ってもいいです。

```javascript
  let count = 0;
  let doubled = 0;
	
  $: computeDouble(count)

  const computeDouble = (count) => {
    console.log(count)
    doubled = count * 2
  }
```

ちなみに`$:`記法は一見へんてこに見えますが、一応正当なJavaScriptです（[label文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loop_Statements/label_Statement)）。

あと正式には reactive declaration（リアクティブ宣言）と呼ばれるようです。

###watch

`watch`も先ほどの`$:`記法で書くことができます。
実際`computed`も`watch`も「データに変化があるたびに何かを行う」という点で共通していますね。

```HTML
<button on:click="{handleClick}">ボタン</button>
<p>count: {count}</p>
<p>count2: {count2}</p>

<script>
  let count = 0
  let count2 = 0

  // countが変化するたびcount2をインクリメント
  $: incrementCount2(count)

  const handleClick = () => {
    count += 1
  }
  const incrementCount2 = () => {
    count2 += 1
  }
</script>
```

この例では、`count`が変化するたびに`incrementCount2()`が呼ばれ、`count2`が`1`増加するようになっています。

###その他
単純なので説明は割愛しますが [v-html](https://svelte.dev/docs#HTML_expressions) や [v-if](https://svelte.dev/docs#If_blocks)、[v-for](https://svelte.dev/docs#Each_blocks) に当たるようなシンタックスも用意されています。

リンク先は英語ですがコードを見ればすぐ理解できるかと思われます。

#終わりに

以上 Vue の基本的な構文に沿って Svelte の文法をざっと説明してきました。

Vue に似た構文で、更に簡潔に書ける部分もあることがわかっていただけたかと思います。

次の JS フレームワークの潮流になるかどうかはわかりませんが、なった場合 Vue ユーザも簡単に移行できそうです。