Snippets & Render
Snippets: ก้อน markup ที่ reuse ได้
หัวข้อที่มีชื่อว่า “Snippets: ก้อน markup ที่ reuse ได้”snippet คือ block ของ markup ที่มีชื่อ ซึ่ง render ซ้ำได้หลายครั้ง นิยามด้วย {#snippet name(params)}…{/snippet} และ render ด้วย {@render name(args)} เป็นวิธีของ Svelte ที่ทำให้ template DRY
<script> let items = $state([ { name: 'Coffee', price: 3 }, { name: 'Tea', price: 2 }, ]);</script>
{#snippet row(item)} <tr><td>{item.name}</td><td>${item.price}</td></tr>{/snippet}
<table> {#each items as item (item.name)} {@render row(item)} {/each}</table>snippet row นิยามครั้งเดียวและ render ต่อ item แต่ละตัว snippet รับ พารามิเตอร์ ได้เหมือนฟังก์ชัน markup เดียวกันจึงปรับตามข้อมูลที่ต่างกันได้
flowchart LR def["snippet row(item) ... end"] --> render1["render row(a)"] def --> render2["render row(b)"] render1 --> out["instance ของ markup"] render2 --> out
Snippets มาแทน slots
หัวข้อที่มีชื่อว่า “Snippets มาแทน slots”ใน Svelte 4 เราส่ง markup เข้า component ด้วย <slot> (และ named slot ผ่าน <slot name="x">) Svelte 5 แทนที่สิ่งนั้นทั้งหมดด้วย snippets — ซึ่งทรงพลังกว่าเพราะรับพารามิเตอร์ได้และเป็นแค่ค่าที่ส่งไปมาได้
<!-- Svelte 4 (เดิม): component นิยาม <slot /> และ <slot name="header" /> --><!-- Svelte 5 (ใหม่): component render {@render children()} และ {@render header()} -->ถ้าคุณอ่าน tutorial เก่าที่ใช้ <slot> ตัวเทียบเท่าสมัยใหม่คือ snippet ที่ render ด้วย {@render} บทถัดไปจะอธิบายว่า parent ส่ง snippet (รวมถึง children snippet พิเศษ) เข้า child อย่างไร
Snippets เป็นค่า
หัวข้อที่มีชื่อว่า “Snippets เป็นค่า”เพราะ snippet เป็นค่า คุณจึงส่ง snippet ไปให้ snippet อื่น เก็บใน variable หรือเลือกระหว่าง snippet แบบมีเงื่อนไขได้:
{#snippet loading()}<p>Loading…</p>{/snippet}{#snippet ready(data)}<p>{data}</p>{/snippet}
{#if isLoading} {@render loading()}{:else} {@render ready(result)}{/if}ความ composable นี้ — snippet เป็น first-class value ที่รับพารามิเตอร์ได้ — คือเหตุผลที่มาแทนกลไก slot ที่ยืดหยุ่นน้อยกว่า