
Nachdem ich Svelte in persönlichen Projekten ausprobiert hatte, wollte ich weitermachen und einen größeren Rahmen in das Projekt einbringen. Zu diesem Zweck habe ich eine Bibliothek mit Komponenten für schlanke Atome geschrieben . Als Grundlage habe ich das UI-Kit für React verwendet, das wir bei der Arbeit verwenden.
Welche Techniken Svelte ich gelernt habe, lesen Sie unter dem Schnitt.
In diesem Artikel wird davon ausgegangen, dass Sie bereits mit den Grundkonzepten von Svelte vertraut sind. Wenn nicht, empfehle ich Ihnen, zuerst meine vorherigen Artikel zu lesen:
Volles Leben auf Svelte
Ein Spiel auf Svelte 3 entwickeln
Die Bibliothek befindet sich in der Phase der aktiven Überarbeitung. Einige Komponenten fehlen noch, Probleme mit der Barrierefreiheit wurden nicht behoben und nicht alle Fehler wurden behoben. Jetzt mache ich ein Projekt für diesen Wal, um im Kampfmodus zu verstehen, was zuerst verbessert werden muss.
Also, was ich durch das Schreiben einer Komponentenbibliothek in Svelte gelernt habe.
1. Verwenden der class -Eigenschaft
Wenn Sie die Klasseneigenschaft zu den Parametern Ihrer Komponente hinzufügen möchten, wird eine Fehlermeldung angezeigt, da das Wort von Javascript selbst reserviert wird.
<script> export let class = ''; </script>
Sie können dieses Problem mit der internen Svelte-API lösen. Die Variable $$ props enthält alle Eigenschaften, die an die Komponente übergeben werden. In der übergeordneten Komponente können Sie die Klasseneigenschaft übergeben
<Component class="someClass" />
Legen Sie in der Komponente selbst die Klasse aus der Variablen $$ props fest .
<div class={$$props.class} />
Beispiel in REPL
2. Styling untergeordneter Komponenten
Svelte verwendet Stilisolation. Wenn Sie einer Komponente eine Klasse hinzugefügt haben, wird ihr ein Hash hinzugefügt, der für Ihre Komponente eindeutig ist und nirgendwo ausläuft. Aber was ist, wenn Sie eine untergeordnete Komponente formatieren müssen? Es ist logisch, ihm eine Klasse zu geben und Stile im Elternteil vorzuschreiben. Dieses Problem wird ganz einfach mit der Direktive gelöst : global ()
<script> import Component from "./Component.svelte"; </script> <div class="parent"> <Component class="childClass" /> </div> <style> .parent :global(.childClass) { color: red; } </style>
Beispiel in REPL
Mit diesem Ansatz erhalten Sie immer noch einen isolierten Stil, der jedoch für die gesamte Hierarchie der untergeordneten Komponenten gilt
3. Handler aller Ereignisse
Die Svelte-Komponente muss das Ereignis unterstützen, damit ihm ein externer Handler zugewiesen werden kann. Das Verschreiben aller Optionen für Ereignisse ist anstrengend. Stattdessen können Sie einen universellen Handler schreiben, der nach Ereignishandlern sucht, die an die Komponente übergeben werden, und diese unserer Komponente hinzufügt. Ich habe die Idee mit AlexxNB in seiner Svelte-Chota-Bibliothek entdeckt .
Beispiel <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} />
Beispiel in REPL
Diese Methode ist nicht ganz legal, da sie die interne Svelte-API verwendet, die sich ändern kann. Ich hoffe, dass in Zukunft die on: * Issue- Direktive auf github hinzugefügt wird
4. Steckplatzerkennung
Wenn Sie herausfinden möchten, ob der Inhalt des Steckplatzes übertragen wird, kann ich Ihnen zwei Optionen anbieten.
Der erste Weg, legal
Die Slots haben einen Fallback, der angezeigt wird, wenn der Inhalt nicht übertragen wird. Nachdem wir den Faltrücken zu einer Variablen gemacht haben, können wir unseren Schlitz erkennen.
<script> let footerRef = null; $: isFooterExists = Boolean(footerRef); </script> <slot name="footer"> <div bind:this={footerRef} /> </slot> {isFooterExists ? ' ' : ' '}
Der zweite Weg, halb legal
Sie können die interne Svelte-API verwenden
const isFooterExists = Boolean($$props.$$slots && $$props.$$slots.footer);
Beispiel in REPL
5. Portale
Svelte akzeptiert keine Portale wie in React, aber es ist sehr einfach. Sie können hierfür die DOM-API verwenden.
<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>
Um die Komponente zu montieren, übertragen wir sie auf den Körper und entfernen beim Entfernen unser Portal.
Wichtiger Hinweis: Wickeln Sie Ihr Portal in ein Div, da Svelte sonst beim Entfernen der Bereitstellung möglicherweise Komponenten falsch entfernt.
6. Animationen
Svelte verfügt über eine große Anzahl vorgefertigter Animationen, die für Sie bei Ihrer Arbeit hilfreich sein können. Es ist sehr einfach, das Auftreten und Verschwinden von Komponenten zu animieren. Das Animieren eines Blocks kann jedoch das Entfernen der gesamten Seite verlangsamen. Svelte wartet, bis die Animation abgeschlossen ist, bevor die Komponente aus dem Baum entfernt wird. Um dies zu vermeiden, verwenden Sie die lokale Direktive.
Tutorial Beispiel
7. Benannte Steckplätze und Komponenten
Leider können Sie eine Komponente nicht sofort in einen benannten Steckplatz übertragen. Ausgabe auf Github
<Component> <Child slot='footer'/> </Component>
Um eine Komponente in einen benannten Steckplatz zu übertragen, wickeln Sie sie in ein div oder ein anderes HTML-Tag ein.
<Component> <div slot='footer'> <Child /> </div> </Component>
8. Abrufen einer Liste der Komponenteneigenschaften
Wenn Sie eine Liste der Eigenschaften benötigen, die aus einer Komponente exportiert werden, können Sie die folgende Konstruktion verwenden:
<script> import Component from './Component.svelte'; const [_, ...props] = Object.getOwnPropertyNames(Component.prototype); </script> {JSON.stringify(props)}
Ich habe die Idee von PaulMaly .
9. Doppelseitige Bindung
Nach der Entwicklung von React wirkt das Konzept der bidirektionalen Bindung einschüchternd, aber nur auf den ersten Blick. Infolgedessen sieht Ihre Anwendung prägnanter aus und ermöglicht es Ihnen, eine Reihe von Handlern loszuwerden. Sie können sowohl eine reguläre Variable als auch einen Speicher als Speicher verwenden.
<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} />
Beispiel in REPL
10. Bearbeitbarer Inhalt
Wenn Sie den Inhalt eines Elements bearbeitbar machen müssen, können Sie die Anweisung contenteditable verwenden und die Werte in eine Variable einbinden.
<script> let value = "Edit me"; </script> <div contenteditable="true" bind:textContent={value}>{value}</div> <div>Value: {value}</div>
Beispiel in REPL
Komponentengröße
Nun, und wo ohne zu reagieren. Vergleichen Sie die Anzahl der Codezeilen der Komponenten in Svelte und React, die ungefähr gleich implementiert sind. Code und Stile werden berücksichtigt.

Demobibliothek
Quellcode
Wenn Sie einen Fehler finden oder etwas vorschlagen möchten, erstellen Sie ein Problem
PS
Am 22. Februar 2020 findet in Moskau das Svelte Russian Meetup # 1 statt. Details und die offizielle Ankündigung im Telegramm an die russische Community-Gruppe Svelte: @sveltejs
Ich lade alle zur Teilnahme ein!