Devahoy Logo
PublishedAt

Svelte

มาลองหัดเขียน Svelte กันดีกว่า

มาลองหัดเขียน Svelte กันดีกว่า

สวัสดีครับ เนื่องจากว่าผมเพิ่งลองหัดเขียน Svelte ก็เลยนำมาเขียนเป็นบทความสรุปเอาไว้ สำหรับคนที่กำลังเริ่มศึกษา เหมือนๆกันกับผม ซึ่งผมมีพื้นฐาน React.js กับ Vue มา ฉะนั้นบางส่วนอาจจะมีข้ามๆ หรือว่าไม่ได้พูดถึง (ขอติต่างว่ามีพื้นฐาน React หรือ Vue มาก่อนแล้ว) ก็ขออภัยด้วยนะครับ หรือถ้าไม่มีพื้นฐาน Frontend อื่นๆ มาก่อน อย่างน้อย ควรรู้ HTML/CSS/JavaScript พื้นฐานนะครับ

Svelte คืออะไร?

  • เป็น Frontend Framework (จริงๆ คือเป็น Compiler) สำหรับทำ UI คล้ายๆ กับ React หรือ Vue
  • ปกติ React จะใช้ DOM drifting แต่ตัว Svelte จะอัพเดทเมื่อ state เปลี่ยน
  • ดูมีความคล้ายคลึงกับ Vue มากกว่า เช่นมีแบ่ง <script> <style> และ markup / template คล้ายๆ Vue SPC (Single Page Component)
  • รองรับ Reactivity เหมือนกับ Vue

เริ่มต้นเรียนรู้ Svelte

แน่นอน เว็บของ Svelte มีข้อมูลเริ่มต้นให้เราแล้ว โดยแบ่งเป็น Tutorials, Docs และ Example ครับ

สำหรับใครที่มีพื้นฐาน React / Vue มาก่อน ก็อาจจะเริ่มจาก Getting Started นี้ดู Overview หรือเริ่มจาก Tutorial ไปทีละขั้นก็ได้ครับ - Svelte Overview

พื้นฐาน Svelte

  • นามสกุลของไฟล์ จะเป็น .svelte เช่น App.svelte มองเป็น Component
  • รูปแบบของไฟล์ svelte จะแบ่งเป็น <script>, markup และ <style> ในไฟล์เดียว
1
<script>
2
// script
3
</script>
4
5
<h1>Hello Svelte!</h1>
6
7
<style>
8
h1 {
9
font-size: 5rem;
10
}
11
</style>
  • เราสามารถประกาศตัวแปร เพิ่มค่า เหมือน JavaScript ปกติเลย ที่แท็ก <script> เช่น
1
<script>const title = 'Hello Svelte'</script>
  • ส่วน markup เราสามารถแสดงค่าตัวแปร ด้วยการใช้ {} ตัวอย่าง
1
<h1>{title}</h1>
  • สามารถใช้ {} ร่วมกับ attributes ก็ได้ เช่น <img src="" />
1
<script>
2
const src = 'https://path/to/image.png'
3
const name = 'short hand'
4
</script>
5
6
<img src={src} alt="demo of {name}" />
  • เมื่อชื่อ attribute กับตัวแปร เหมือนกัน เราสามารถเขียนแบบย่อได้
1
<img {src} alt="short hand" />
  • เรื่องของ stylesheet ก็เหมือน CSS ปกติเลย เขียนภายใน tag <style> และก็ตัว CSS จะมีผลเฉพาะไฟล์นี้ (component scoped) เช่น ถ้าเรากำหนด h1 มีสีแดง ก็จะมีแดงแค่ component นี้ ไม่มีผลกับ component อื่นๆ ตัดปัญหาเรื่อง selector ซ้ำไปได้เลย
  • การ import Component ก็คล้ายๆ Vue หรือ React คือการ import file ที่เป็น component มา จากนั้นก็ เพิ่มใน markup ตัวอย่างเช่นมี Child.svelte และ Parent.svelte
1
<script>
2
import Child from './Chlid.svelte'
3
</script>
4
5
6
<Child />

ตัวอย่างข้อมูลในไฟล์ Child.svelte

1
<h1>This is child component</h1>

Reactivity

feature นี้ตัว Svelte บอกว่าเป็นหัวใจหลักเลย ก็คือมันจะทำหน้าที่คอย sync DOM element กับ application state ของเรา เช่นค่า onclick หรือ user input หรือการเปลี่ยน data ต่างๆ เพื่ออัพเดทข้อมูลอัตโนมัติ (เปลี่ยนค่า DOM)

  • ตัวอย่างการ handle onclick ใช้ on:click directive ซึ่งรูปแบบของมันคือ on:eventname เช่น on:click, on:mouseenter หรือ on:input เป็นต้น
1
<script>
2
let count = 0;
3
4
function incrementCount() {
5
count += 1;
6
}
7
</script>
8
9
<button on:click={incrementCount}>
10
Clicked {count} {count === 1 ? 'time' : 'times'}
11
</button>
  • จากโค๊ดด้านบน เมื่อคลิ๊ก button ค่า count จะเพิ่มทีละ 1 และหน้าเว็บ ก็จะแสดงผลค่า count อัพเดท realtime นั่นเอง
  • เราสามารถ sync ค่าจากตัวแปรอื่นๆ ก็ได้ ด้วยการใช้ $: ตัวอย่าง doubled จะถูกอัพเดททุกครั้งที่ count มีการเปลี่ยนค่า
1
<script>
2
let count = 0;
3
$: doubled = count * 2;
4
5
function handleClick() {
6
count += 1;
7
}
8
</script>
9
10
<button on:click={handleClick}>
11
Clicked {count} {count === 1 ? 'time' : 'times'}
12
</button>
13
14
<p>{count} doubled is {doubled}</p>
  • reactivity กับพวก array หรือ object ต้องเป็น immutable เท่านั้น จะไม่มีผลกับ mutable data เช่น ไป array.push(), pop() อะไรพวกนั้น

Props

  • การกำหนด component properties ทำได้ง่ายๆ ด้วยการ กำหนด ตัวแปรเป็น export เช่น มีไฟล์ชื่อ Hello.svelte
1
<script>export let title</script>
  • เวลาเพิ่มใน markup ก็ส่ง props (attribute) ไปแบบนี้
1
<Hello title="This is title" />
  • กำหนด props เป็น optional ได้ ด้วยการ assign ค่า default value เอาไว้ (ถ้าไม่มี props ส่งมา ก็จะใช้ค่าเริ่มต้น)
1
<script>export let title = 'default title'</script>

Logic

  • Logic การ render เป็น block ผมว่าอ่านง่ายกว่า React (ถ้าเทียบกับมือใหม่ เพราะหลายๆ คนจะงงๆ ternary operator ใน JSX)
  • ใช้ block #if <condition> ได้เลย แบบนี้
1
{#if user.loggedIn}
2
<button on:click={logout}>
3
Log out
4
</button>
5
{/if}
  • การใช้ if/else จะใช้แบบนี้
1
{#if user.loggedIn}
2
<button on:click={toggle}>
3
Log out
4
</button>
5
{:else}
6
<button on:click={toggle}>
7
Log in
8
</button>
9
{/if}
  • ข้อสังเกต {#if} สำหรับเริ่มต้น block {/if} สำหรับปิด block แต่ถ้ามี ต่อเนื่องใน block จะใช้ {:else} เช่นเดียวกับ {:else if}
  • การ loop ข้อมูล จะใช้ {#each expression as name}...{/each} เช่น
1
<ul>
2
{#each cats as cat}
3
<li>
4
<a target="_blank" href="https://www.youtube.com/watch?v={cat.id}" rel="noreferrer">
5
{cat.name}
6
</a>
7
</li>
8
{/each}
9
</ul>
  • สามารถใช้ destructuring ได้เช่นกัน
1
{#each cats as { id, name }}
  • list เราควรกำหนด key ให้มันด้วย เพื่อเป็น unique identifier
1
{#each cats as cat, (cat.id)}
  • เราสามารถทำ async data ด้วยการใช้ await block {#await promise} ได้ด้วย ลองดูตัวอย่าง https://svelte.dev/examples/await-blocks
  • การ bind value กับ input (ให้ความรู้สึกเมื่อสมัย AngulasJS ออกมาเลย) เราใช้ syntax bind:value={variable} ตัวอย่าง
1
<script>
2
let name = 'world';
3
</script>
4
5
<input bind:value={name}>
6
7
<h1>Hello {name}!</h1>

ทั้งหมดนี้ก็เป็นตัวอย่างคร่าวๆ การใช้ Svelte นะครับ ซึ่งผมก็นำมาเขียนเป็นสรุปจากที่อ่าน Tutorial และก็ดู Example คร่าวๆครับ จริงๆ ยังมีอีกหลายเรื่องที่ยังไม่ได้พูดถึง ก็ลองไปศึกษากันดูนะครับ ใครที่มีพื้นฐานจาก Vue/React คิดว่าอ่านแปปๆเดียวก็ทำได้แล้วครับ

สุดท้ายหลังจากลองอ่านแล้ว ลองไปฝึกทำกันดูจริงๆ ด้วยการใช้ SvelteKit ขึ้นโปรเจ็คก็ดีนะครับ แล้วเดี๋ยวบทความหน้าผมจะลองไปหัดใช้ SvelteKit และมาสรุปเป็นบทความไว้เหมือนเดิมครับ ขอบคุณครับ

Happy Coding ❤️

Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts