
Setelah mencoba Svelte dalam proyek pribadi, saya ingin melanjutkan dan mengambil kerangka kerja yang lebih besar ke dalam proyek. Untuk melakukan ini, saya menulis perpustakaan komponen langsing-atom . Sebagai dasar, saya mengambil kit UI pada React, yang kami gunakan di tempat kerja.
Teknik apa yang saya pelajari, baca di bawah potongan.
Artikel ini mengasumsikan bahwa Anda sudah terbiasa dengan konsep dasar Svelte. Jika tidak, saya sarankan Anda membaca artikel saya sebelumnya:
Kehidupan penuh di Svelte
Mengembangkan game di Svelte 3
Perpustakaan sedang dalam fase revisi aktif. Beberapa komponen masih hilang, masalah aksesibilitas belum diperbaiki, dan tidak semua bug telah diperbaiki. Sekarang saya sedang melakukan proyek pada paus ini untuk memahami dalam mode pertempuran apa yang perlu ditingkatkan terlebih dahulu.
Jadi, apa yang saya pelajari dengan menulis perpustakaan komponen di Svelte.
1. Menggunakan properti kelas
Jika Anda ingin menambahkan properti kelas ke parameter komponen Anda, Anda akan mendapatkan kesalahan, karena kata itu dipesan oleh javascript itu sendiri.
<script> export let class = ''; </script>
Anda dapat mengatasi masalah ini menggunakan api Svelte internal. Variabel $$ props berisi semua properti yang diteruskan ke komponen. Di komponen induk, Anda bisa melewati properti kelas
<Component class="someClass" />
Dan dalam komponen itu sendiri, atur kelas dari variabel $$ props .
<div class={$$props.class} />
Contoh dalam REPL
2. Menata komponen anak
Svelte menggunakan isolasi gaya. Jika Anda menambahkan kelas dalam komponen, maka hash akan ditambahkan ke dalamnya dan itu akan unik untuk komponen Anda dan tidak akan bocor di mana pun. Tetapi bagaimana jika Anda perlu mendesain komponen anak? Adalah logis untuk memberinya kelas dan meresepkan gaya di induknya. Masalah ini diselesaikan dengan cukup sederhana, menggunakan arahan : global ()
<script> import Component from "./Component.svelte"; </script> <div class="parent"> <Component class="childClass" /> </div> <style> .parent :global(.childClass) { color: red; } </style>
Contoh dalam REPL
Dengan pendekatan ini, Anda masih mendapatkan gaya yang terisolasi, tetapi itu berlaku di seluruh hierarki komponen anak
3. Penangan semua acara
Komponen Svelte harus mendukung acara sehingga penangan eksternal dapat ditugaskan untuk itu. Meresepkan semua opsi untuk acara itu melelahkan. Sebagai gantinya, Anda dapat menulis penangan universal yang akan mencari penangan acara yang diteruskan ke komponen dan menambahkannya ke komponen kami. Saya melihat ide itu dengan AlexxNB di perpustakaannya yang langsing .
Contoh <script> import { current_component, bubble, listen } from "svelte/internal"; function getEventsAction(component) { return node => { const events = Object.keys(component.$$.callbacks); const listeners = []; events.forEach(event => listeners.push(listen(node, event, e => bubble(component, e))) ); return { destroy: () => { listeners.forEach(listener => listener()); } }; }; } const events = getEventsAction(current_component); export let value; </script> <input use:events {value} />
Contoh dalam REPL
Metode ini tidak sepenuhnya legal, karena menggunakan API Svelte internal, yang dapat berubah. Saya berharap di masa depan mendukung untuk pada: * Arahan masalah akan ditambahkan di github
4. Deteksi Slot
Jika Anda perlu mencari tahu apakah isi slot ditransfer, maka saya dapat menawarkan dua opsi.
Cara pertama, legal
Slot memiliki cadangan yang ditampilkan jika konten tidak ditransfer. Setelah membuat backing lipat menjadi variabel, kami dapat mendeteksi slot kami.
<script> let footerRef = null; $: isFooterExists = Boolean(footerRef); </script> <slot name="footer"> <div bind:this={footerRef} /> </slot> {isFooterExists ? ' ' : ' '}
Cara kedua, semi legal
Anda dapat menggunakan api Svelte internal
const isFooterExists = Boolean($$props.$$slots && $$props.$$slots.footer);
Contoh dalam REPL
5. Portal
Svelte tidak menerima portal, seperti dalam Bereaksi, tetapi sangat mudah dilakukan. Anda dapat menggunakan api DOM untuk ini.
<script> import { onMount } from "svelte"; let ref; onMount(() => { document.body.appendChild(ref); return () => { document.body.removeChild(ref); }; }); </script> <div> <div bind:this={ref}>content</div> </div>
Untuk memasang komponen, kami memindahkannya ke badan, dan saat melepas, kami menghapus portal kami.
Catatan penting: bungkus portal Anda dalam sebuah div, jika tidak, Svelte dapat menghapus komponen dengan salah saat melepas pemasangan.
6. Animasi
Svelte memiliki serangkaian besar animasi yang sudah jadi yang mungkin berguna bagi Anda dalam pekerjaan Anda. Sangat mudah untuk menghidupkan dan mematikan komponen. Tetapi menghidupkan satu blok bisa memperlambat penghapusan seluruh halaman. Svelte akan menunggu animasi selesai sebelum menghapus komponen dari pohon. Untuk menghindari ini, gunakan arahan lokal .
Contoh tutorial
7. Slot dan komponen yang dinamai
Sayangnya, Anda tidak dapat mentransfer komponen ke slot bernama segera. Masalah di github
<Component> <Child slot='footer'/> </Component>
Untuk mentransfer komponen ke slot bernama, bungkus dalam div atau tag html lainnya.
<Component> <div slot='footer'> <Child /> </div> </Component>
8. Mendapatkan daftar properti komponen
Jika Anda perlu mendapatkan daftar properti yang diekspor dari komponen, maka Anda dapat menggunakan konstruksi berikut:
<script> import Component from './Component.svelte'; const [_, ...props] = Object.getOwnPropertyNames(Component.prototype); </script> {JSON.stringify(props)}
Saya mendapat ide dari PaulMaly .
9. Mengikat dua sisi
Setelah berkembang di React, konsep pengikatan dua arah tampaknya menakutkan, tetapi hanya pada pandangan pertama. Akibatnya, aplikasi Anda akan terlihat lebih ringkas dan memungkinkan Anda untuk menyingkirkan sekelompok penangan. Anda dapat menggunakan variabel biasa dan menyimpan sebagai penyimpanan.
<script> import Input from "./Input.svelte"; import { writable } from "svelte/store"; let letValue = "test let"; const storeValue = writable("test store"); </script> <Input bind:value={letValue} /> <Input bind:value={$storeValue} />
Contoh dalam REPL
10. Konten yang Dapat Diedit
Jika Anda perlu membuat konten elemen dapat diedit, maka Anda dapat menggunakan arahan contenteditable dan mengikat nilai-nilai ke dalam variabel.
<script> let value = "Edit me"; </script> <div contenteditable="true" bind:textContent={value}>{value}</div> <div>Value: {value}</div>
Contoh dalam REPL
Ukuran Komponen
Nah, dan di mana tanpa Bereaksi. Menyimpan perbandingan jumlah baris kode komponen pada Svelte dan React, yang diterapkan kira-kira sama. Kode dan gaya diperhitungkan.

Perpustakaan demo
Kode sumber
Jika Anda menemukan bug, atau ingin menyarankan sesuatu, buat masalah
PS
22 Februari 2020 akan diadakan Svelte Russian Meetup # 1 di Moskow. Detail dan pengumuman resmi dalam telegram ke grup komunitas Rusia Svelte: @sveltejs
Saya mengundang semua orang untuk berpartisipasi!