Apa yang saya pelajari dengan menulis perpustakaan komponen di Svelte


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!

Source: https://habr.com/ru/post/id473598/


All Articles