Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vue ユーザーが Svelte に⼊⾨してみた

SAW
October 06, 2023

Vue ユーザーが Svelte に⼊⾨してみた

Kyoto.js 20 の発表資料です。

SAW

October 06, 2023
Tweet

More Decks by SAW

Other Decks in Programming

Transcript

  1. 2 023 / 10 / 05 SAW Vue ユーザーが Svelte

    に⼊⾨してみた Kyoto.js 2 0
  2. $(whoami) • ⽒名: 加藤 宗⼀郎 (29歳) • ハンドルネーム: SAW •

    ⼤阪在住‧愛知出⾝ • Twitter: @azuki_eater • 得意分野 • Web アプリケーション開発 (Laravel, Vue) • 約 1年ぶりの登壇 • オフラインは約 3年ぶり 
  3. Svelte とは • JavaScript フレームワークの 1つ • 仮想 DOM を利⽤しない

    • TypeScript も公式対応 • 近年最も熱いフレームワーク • 興味のあるフレームワーク 1位 • 2020年~2022年で 3年連続 1位  https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/
  4. Vue とは • JavaScript フレームワークの 1つ • React, Angular についで広く利⽤されている

    • 仮想 DOM を利⽤ • Vue 3 で⼤きなアップデート • Composition API という新たな記法が追加 • TypeScript に公式対応  https://2022.stateofjs.com/en-US/libraries/front-end-frameworks/
  5. Vue と Svelte は記法が似ている • コンポーネント単位でビューとロジックを記載可能 • HTML, CSS, JavaScript

    を 1 つのファイルに記載 • データバインディングやイベントハンドラの登録の記法が類似 • Vue 3 の Composition API と類似 • Vue ユーザーに特に馴染みやすい (と思う) 
  6. Svelte のプロジェクトの作成 • Vite から Svelte のテンプレートを選択することで作成可能 • Vite: 様々なフレームワークに対応したフロントエンドの爆速ビルドツール

    • オプション --template に svelte を指定 • TypeScript を利⽤する場合は svelte-ts を指定  # npm を利用する場合 npm create vite project-name -- --template svelte # yarn を利用する場合 yarn create vite project-name --template svelte
  7. コンポーネントの定義 • 1つのファイルをコンポーネントとしてビューとロジックを定義 • Vue では Single File Component (SFC)

    と呼ばれる • ビューの定義: HTML タグをテンプレートとして記述 • スタイルの定義: style タグ内に CSS を記述 • ロジックの定義: script タグ内に JavaScript を記述 • TypeScript の利⽤時は script タグに lang="ts" を指定 
  8. ビューテンプレートの記述 • テンプレート内にロジックの変数の内容を表⽰可能 • Svelte: {変数名} で表⽰ • Vue: {{

    変数名 }} で表⽰ • プロパティにロジックの変数の内容を反映が可能 • Svelte: プロパティ名={変数名} で反映 • Vue: v-bind:プロパティ名="変数名" 
  9. ⽐較: ビューテンプレートの記述  <script> let name = 'Jack'; let url

    = 'https://example.com'; </script> <p>Hello, {name}.</p> <p>Click <a href={url}>here</a></p> <script setup> const name = 'Jack'; const url = 'https://example.com'; </script> <template> <p>Hello, {{ name }}.</p> <p>Click <a v-bind:href="url">here</a></p> </template> Svelte の場合 Vue の場合
  10. 変数のバインディング • バインディング: ビューとロジック内の変数を結びつける概念 • 双⽅向にバインディングが可能 • 変数の変更を DOM 要素に即座に反映

    • <input> などの変更をロジックの変数に即座に反映 • Svelte の場合は bind:プロパティ名={変数名} と明⽰的に記載 • ロジックからの変更は値を再代⼊しないと検知されない • Vue の場合は ref() で初期化した変数が双⽅向バインディングになる  Hello, world. Hello, world. message テキストフォームの⼊⼒内容を 変数 message に即時反映 変数 message の変更内容を テキストフォームに即時反映
  11. ⽐較: 変数のバインディング  <script> let message = 'Hello'; </script> <p>{message}</p>

    <!-- value プロパティを双方向バインディング --> <input bind:value={message}> <script setup> import { ref } from 'vue'; const message = ref('Hello'); </script> <template> <p>{{ message }}</p> <!-- value プロパティを双方向バインディング --> <input v-model="message"> </template> Svelte の場合 Vue の場合
  12. テンプレート内の条件分岐‧繰り返し • テンプレート内で条件に応じて表⽰内容を変更可能 • Svelte: {#if 条件式} 〜 {/if} ブロック

    • Vue: v-if ディレクティブ • 配列の要素に基づいて繰り返し表⽰が可能 • Svelte: {#each 配列 as 変数} 〜 {/each} • Vue: v-for ディレクティブ 
  13. ⽐較: テンプレート内の条件分岐‧繰り返し  <script> let array = [0, 1, 2,

    3, 4]; </script> {#each array as item} {#if item % 2 === 0} <p>{item}: Even</p> {:else} <p>{item}: Odd</p> {/if} {/each} <script setup> import { ref } from 'vue'; const array = ref([0, 1, 2, 3, 4]); </script> <template> <template v-for="item in array"> <p v-if="item % 2 === 0">{{item}} :Even</p> <p v-else>{{item}} :Odd</p> </template> </template> Svelte の場合 Vue の場合
  14. リアクティブステートメント • 依存する変数が変更された際に実⾏される⽂ • ⽂の先頭に $: を記述 • ブロックで囲むことで複数の⽂を実⾏可能 •

    Vue の computed と watch を⾜したような機能 • computed: 変数の値の変更に依存して値が再計算されるプロパティ • watch: 変数の値が変更された際に実⾏される処理 
  15. ⽐較: リアクティブステートメントと computed  <script> let h = 170.0; let

    w = 60.0; $: bmi = (w / ((h / 100) ** 2)).toFixed(2); </script> <p><input bind:value={h}> cm</p> <p><input bind:value={w}> kg</p> <p>BMI: {bmi}</p> <script setup> import { ref, computed } from 'vue'; const h = 170.0; const w = 60.0; const bmi = computed(() => (w.value / ((h.value / 100) ** 2)).toFixed(2)); </script> <template> <p><input v-model="h"> cm</p> <p><input v-model="w"> kg</p> <p>BMI: {{ bmi }}</p> Svelte の場合 Vue の場合
  16. イベントハンドラの登録 • DOM イベントや独⾃のイベントにハンドラを設定 • on:イベント名={関数} でイベントハンドラを登録 • 独⾃のイベントはコンポーネントイベントと呼称 

    <script> function hello() { alert('Hello'); } </script> <button on:click={hello}>Greet</button> <script setup> function hello() { alert('Hello'); } </script> <template> <button v-on:click="hello">Greet</button> </template> Svelte の場合 Vue の場合
  17. コンポーネントイベントの定義 • svelte パッケージの createEventDispatcher を利⽤ • createEventDispatcher() が返却する関数を実⾏することでイベントを発⽕ 

    <script> import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher(); const onClick = () => dispatch('greet', 'Hi'); </script> <button on:click={onClick}>Greet</button> <script> import GreetButton from './GreetButton.svelte'; const greet = e => alert(e.detail); </script> <GreetButton on:greet={greet} /> greet イベント 発⽕
  18. コンポーネントのプロパティ • Svelte では変数を export することでプロパティとして定義 • プロパティとして宣⾔する変数には let 修飾⼦を利⽤

    • 宣⾔時に値を代⼊することで初期値を設定可能 • プロパティの値は親と⼦コンポーネントの双⽅から変更可能 • Vue の場合は⼦コンポーネントからプロパティを直接変更不可 • ⼦から独⾃イベントを発⽕して親からプロパティを変更 • defineProps() でプロパティを定義 • defineEmits() で独⾃イベントを定義 
  19. Svelte コンポーネントのプロパティの更新  <script> export let value = 'Hello, world!';

    </script> <input bind:value={value}> <script> import InputBox from './InputBox.svelte'; let message = 'Hi.'; </script> <InputBox bind:value={message} /> value プロパティに 変数 message を バインディング • input から value プロパティを変更 • 変更内容は親から渡された変数に即時反映
  20. ⽐較: Vue コンポーネントのプロパティの更新  <script setup> import { ref }

    = 'vue'; const props = defineProps(['value']); const emit = defineEmits('update']); const inputValue = ref(props.value); const onChange = ({target}) => { inputValue.value = target.value; emit('update', inputValue.value); }; </script> <template> <input v-bind:value="inputValue" v-on:input="onChange"> </template> <script setup> import { ref } from 'vue'; import InputBox from './InputBox.svelte'; const message = 'Hi.'; const onUpdate = value => message.value = value; </script> <InputBox v-bind:value="message" v-on:update="onUpdate" /> value プロパティに 変数 message を バインディング •update イベント発⽕ •onUpdate ハンドラで message の値を更新
  21. Svelte と Vue の記法で異なる点 • Svelte • Vue の setup

    のような記述が不要 • Vue ではテンプレートに変数をバインディングするために必要 • プロパティの値が親⼦関係なく直接変更可能 • Vue では⼦コンポーネント側からプロパティを直接変更不可 • Vue • バインディングやイベントハンドラの登録で省略形が存在 • リアクティブな変数の変更を代⼊以外でも検知可能 • Array.push() などのメソッドからの値の変更を検知可能 
  22. 総括 • Svelte の概要を紹介 • ⽐較対象の Vue についても紹介 • Svelte

    の基本機能を紹介 • Vue の記法と類似していることを確認 • コンポーネントのプロパティのように異なる部分も紹介