Help us understand the problem. What is going on with this article?

Vue・Reactを超える!? 近年話題の Svelte に入門してみよう!

はじめに

今回は最近ちょいちょい使われているフロントエンドフレームワーク Svelte.jsについて解説します1
最近だと、ロイターの大統領選挙ページで使われてましたね。

Svelte.jsは速くて軽く、簡単に実装できるフレームワークです。

どうやら、React, Vue, Angular, Emberよりも速いらしいです!
https://svelte.dev/blog/frameworks-without-the-framework#Introducing_Svelte

Tutorialも充実しており、サイト上で実際に書きながら学ぶこともできます。

本記事はTutorialを触る前に、ざっと概要を学びたい方向けに書いてます!

YouTube動画

動画で確認したい方はこちらもどうぞ。
【YouTube動画】 VueやReactを超える!? 次世代のフロントエンドフレームワーク Svelte.jsをご紹介!!
VueやReactを超える!? 次世代のフロントエンドフレームワーク Svelte.jsをご紹介!!

基本の書き方

それでは基本の書き方をみていきます。
Tutorialを始める前に、さらっと読んでおくと理解が捗ると思います!

変数の使い方

svelte.jsでは、scriptタグ内でletを定義するだけで変数として利用できます。

<!-- svelte.js -->
<script>
  let name = 'World';
</script>

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

Vue.jsで同じように出力しようとすると、以下のようになります。
svelteと比較して、記述量が多めです。

<!-- vue.js -->
<template>
  <h1> Hello, {{ name }} !! </h1>
</template>

<script>
export default {
  data() {
    return {
      name: "World"
    }
  } 
}
</script>

属性の使い方

属性の書き方も簡単です!
vueで画像を表示しようとすると次のようになります。

<!-- vue.js -->
<template>
  <img :src="image" alt='yassun youtube' />
</template>

<script>
export default {
  data() {
    return {
      image: "https://img.youtube.com/vi/rbhMST4A1Hs/0.jpg",
    };
  },
};
</script>

svelteだともっと簡単に書くことができます。
ちなみに、altを省略すると、A11y (Accessibility) の警告が出てきます。

<!-- svelte.js -->
<script>
  let src="https://img.youtube.com/vi/rbhMST4A1Hs/0.jpg"
</script>


<main>
  <img {src} alt='yassun youtube'>
</main>

styleの書き方

styleに直接記述するだけで、スタイルを当てることができます。
また、デフォルトでスコープがコンポーネント内になるため、クラス名の競合を意識しなくて大丈夫です。

<!-- svelte.js -->
<style>
  p {
    color: purple;
  }
</style>

<p>テスト!</p>

他コンポーネントの使い方

インポートするだけで使えます。

<script>
  import Nested from './Nested.svelte'
</script>

<Nested />

Reactive

on:イベントでイベント発火条件を書き、scriptタグ内のメソッドを呼び出すだけで、メソッドが使えます。
vueのようにmethodsを定義する必要がありません。

<script>
  let count = 0;

  function handleClick() {
    count += 1;
  }
</script>

<button on:click={handleClick}>{ count }</button>

preventDefaultやstopPropagationの追加もパイプで繋ぐだけで、簡単にできます。

<script>
  function handleForm() {
    console.log('handleForm');
  }
</script>

<form on:submit|preventDefault={handleForm}>
  <button>ボタン</button>
</form>

ある変数と連動して別のコードが動いて欲しい場合には、$:を使います。
例えば、scriptタグに以下のように書くと、countが変化した時にコンソールにログが流れます。

let count = 0;

$: console.log(`count: ${count}`);

変化するコードをグルーピングしたい場合は{}で括ります。

let count = 0;

$: {
  console.log('hello');
  console.log(`count: ${count}`);
}

ifで別途、コードが連動する条件を指定することもできます。
以下の場合は、countが2以上になったら、動きます。

let count = 0;

$: if (count >= 2) {
  console.log(`count: ${count}`);
}

props

propsはscript内でexportするだけで、別のコンポーネントで使えるようになります。
exportする際にデフォルト値を指定することもできます。

<!-- Child.svelte -->
<script>
 export let answer;
</script>

<p>{ answer }</p>
<script>
  import Child from './Child.svelte'
</script>

<Child answer={10} />

slot

slotはこんな感じで入れます。

Comp.svelte

<div>
  <slot></slot>
</div>

App.svelte

<script>
  improt Comp from './Comp.svelte'
</script>

<Comp>
  <div>スロット</div>
</Comp>

if

if文はこのように書きます。
/ifでif文の終わりを決めます。

{#if count > 10 }
  <p>Big!!</p>
{:else if count > 5 }
  <p>Medium</p>
{:else}
  <p>Small</p>
{/if}

await

awaitはif文と似たような感じで書けます。

{#await promise}
  <p>waiting...</p>
{:then number}
  <p>number is {number}</p>
{:catch error}
  <p>{error.message}</p>
{/await}

loop (each)

for文に慣れていると間違えそうですが、cats as catというように、各要素はasの右側に書きます。

{#each cats as cat, i}
  <div>{i}-th cat is {cat}</div>
{/each}

bind

bindはvueっぽく書けます。

<input bind:value={name}>

Lifecycle

ライフサイクルのメソッドは以下のように、svelteからインポートして使います。
onMount, onDestroy, beforeUpdate, afterUpdate, tickなどが用意されています。

<script>
  import { onMount } from 'svelte';

  let test = '';

  onMount(async () => {
    test = await somePromise();
  })
</script>

<p>{ test }</p>

Store

storeもsvelteに入っているため、以下のようにして使うことができます。
writable(0)をセットすることで、値のupdate, set, subscribeが使えるようになります。

他にもsvelte/storeには、読み込み専用のreadableや別のstoreを使って新しくstoreを作るderivedなどがあります。

import { writable } from 'svelte/store';

export const test = writable(0);

test.update(n => n + 1)
test.set(x)
test.subscribe(value => {})

{ $test }

以下のようにメソッドを制限したカスタムstoreを作成することもできます。
ここら辺の詳しい話もTutorialに詳細があるので、ぜひ確認してみてください。

function createCount() {
  // writable(0)をセットし、メソッドを呼び出す
  const { subscribe, set, update } = writable(0);

  return {
    subscribe,
    // 値を1だけ増やすメソッドを設定
    increment: () => update(n => n + 1),
    // 値を1だけ減らすメソッドを設定
    decrement: () => update(n => n - 1),
    reset: () => set(0)
  };
}

おわりに

Svelte.jsを試してみたくなりましたか?
簡単に始めることができるので、ぜひ試してみてください!

Tutorialはこちら
https://svelte.dev/tutorial/basics

自由に触りたい方は以下の方法もオススメです!
Svelteの公式ページでREPLを試す。
https://svelte.dev/repl

CodeSandboxのSvelte.jsのテンプレートを試す。
https://codesandbox.io/dashboard/home

npxでローカルにインストールして試す。
https://svelte.dev/blog/the-easiest-way-to-get-started


  1. 公式サイトでもフレームワークと名乗っているので、フレームワークという語を使います。https://svelte.dev/blog/frameworks-without-the-framework#Introducing_Svelte 

yassun-youtube
教育系エンジニアやっすんがエンジニアに役立つTipsを毎日紹介するYouTubeチャンネル「やっすんのエンジニア大学」をやっています。 エンジニアリングに興味のある方全員が知って得するTIPSをお届けしています!
https://www.youtube.com/channel/UCajrdoGzHzDogrNrLYYmGsg/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away