Svelteのプロジェクト作成から基本的な機能を試してみた
最近注目集めている Svelte を軽く触ってみた。 react や vue と比べて、特殊な概念が少なく非常に簡潔に変える印象。 軽量なアプリケーションだったら svelte を使うのがいいかもと言うのが、軽く触った感想。
svelte は内部で仮想 dom を使わないことで、高速にレンダリングを実現しているとのこと。react/vue はブラウザ側で仮想 dom を扱うランタイムをビルド結果に含めるので、容量が大きくなるらしい。また仮想 dom を通してレンダリングすることで、そのオーバーヘッドのため若干遅くなるらしい
プロジェクト作成から起動まで
以下のコマンドで svelte のプロジェクトが作成できる。
npx degit sveltejs/template svelte-smaple-app
.
├── README.md
├── package.json
├── public
│ ├── build
│ ├── favicon.png
│ ├── global.css
│ └── index.html
├── rollup.config.js
├── scripts
│ └── setupTypeScript.js
├── src
│ ├── App.svelte
│ ├── components
│ ├── main.js
│ └── pages
├── yarn-error.log
└── yarn.lock
pages と components に関しては作成した。
pages はルーティングの起点となるページコンポーネントを配置して、components にはページコンポーネント等から使用するコンポーネントを配置するようにした。
ルーティング
ルーティングの機構は今回のテンプレートに含まれてないので、インストールしておく
yarn add svelte-routing
App.svelte
<script>
import { Router, Link, Route } from "svelte-routing";
import Home from "./pages/Home.svelte";
import MyPage from "./pages/MyPage.svelte";
</script>
<Router url="{url}">
<nav>
<Link to="/">Home</Link>
<Link to="mypage">MyPage</Link>
</nav>
<div>
<Route path="/"><Home /></Route>
<Route path="mypage" component="{MyPage}" />
</div>
</Router>
/のホームと/mypage のマイページを作成する。
pages/Home.svelte
<h1>HOME</h1>
pages/MyPage.svelte
<h1>MyPage</h1>
HTML を直接書くだけで OK。JS をの記述は必要なければいらない
リアクティブな値を操作する
マイページを編集して、リアクティブな値を操作してみる pages/MyPage.svelte
リストへの値の追加
空のリストを用意し、ボタンを押すことで、そのリストに 1 という数字を追加する機能を実装してみる
js は script タグ内に記述すれば OK
<script>
let countList = []
const countUp = () => {
console.log("count up")
countList = [...countList, 1]
}
</script>
<div>
<div>
<button on:click={countUp}>UP</button>
</div>
countListLength: {countList.length}
<ul>
{#each countList as count}
<li>{count}</li>
{/each}
</ul>
</div>
svelte は react/vue などと違ってリアクティブな値の宣言を特殊な記法で記述する必要はない。この辺は結構楽ではあるが、リアクティブな値とそうでない値の見分けがツナかくなるので、編集名などを工夫するなどしたほうがいいかも
if 文や繰り返し文を html 内で記述する場合は、svelte 独自の記法が必要になる。今回であればリストの繰り返しは each という構文を使っている。
countUp 関数中では新しいリストを再作成して代入している。これは、countList.push をしても値の変更を検知できないためらしい
https://svelte.dev/tutorial/updating-arrays-and-objects
リアクティブな値の監視
次は input エリアを 2 つ設けて、入力した通知の合計値を表示するプログラムを記述する
<script>
let form = {
v1: 0,
v2: 0
}
$: sum = form.v1 + form.v2
$: if(sum === 10 ) {
// watchっぽく使える
console.log("10きた")
}
</script>
<div>
<div>
<input type="number" bind:value={form.v1} />
<input type="number" bind:value={form.v2} />
</div>
<div>{sum}</div>
</div>
まずリアクティブな値を input にバインドする場合は bind:value という記述を利用する。react では値を変更するような function を用意したり、vue では v-model を使ったりするところに当たる。 slvete は直感的でわかりやすい記述になっている。value はオブジェクトのネストしたプロパティも使える
v1 と v2 の値を sum に入れる処理を記述しているが、ここが特殊な記述となっている。
let で sum を定義した場合は、v1/v2 が変化してもその変化を検知して sum がリアクティブに変わることはない。 この記述は vue でいう computed と同じ react の useState や vue の computed と比べるとかなり記述が簡略化されている
便利な公式チュートリアル
svelte は公式 doc でチュートリアルを実行しながら学べるので、学習しやすい https://svelte.dev/tutorial/basics
このようにプレイグラウンドを用意してくれてるので、学習のハードルが低い
今回のような簡単で基本的な記述であれば svelte は react/vue と比べても記述量が少なく、直感的にかけるので、簡単なアプリケーション開発には向いてるかもしれない。 ただサードパーティのプラグインやライブラリが react/vue と比べると少ないので、大規模開発で使うと自分で実装しなければならないところが増えるかもしれない。個人開発での管理画面を作る場合などに重宝しそう