Ce que j'ai appris en écrivant une bibliothèque de composants dans Svelte


Ayant essayé Svelte dans des projets personnels, je voulais avancer et intégrer un cadre plus large dans le projet. Pour ce faire, j'ai écrit une bibliothèque de composants svelte-atomes . Comme base, j'ai pris le kit d'interface utilisateur sur React, que nous utilisons au travail.


Quelles techniques Svelte j'ai apprises, lisez sous la coupe.


Cet article suppose que vous connaissez déjà les concepts de base de Svelte. Sinon, je vous recommande de lire d'abord mes articles précédents:
Pleine vie sur Svelte
Développement d'un jeu sur Svelte 3


La bibliothèque est en phase de révision active. Certains composants sont toujours manquants, les problèmes d'accessibilité n'ont pas été résolus et tous les bogues n'ont pas été corrigés. Maintenant, je fais un projet sur cette baleine afin de comprendre en mode combat ce qui doit être amélioré en premier.


Donc, ce que j'ai appris en écrivant une bibliothèque de composants dans Svelte.


1. Utilisation de la propriété de classe


Si vous souhaitez ajouter la propriété de classe aux paramètres de votre composant, vous obtiendrez une erreur, car le mot est réservé par javascript lui-même.


<script> export let class = ''; // !!!  !!! </script> 

Vous pouvez résoudre ce problème en utilisant l'API Svelte interne. La variable $$ props contient toutes les propriétés transmises au composant. Dans le composant parent, vous pouvez transmettre la propriété de classe


 <Component class="someClass" /> 

Et dans le composant lui-même, définissez la classe à partir de la variable $$ props .


 <div class={$$props.class} /> 

Exemple dans REPL


2. Styliser les composants enfants


Svelte utilise l'isolement de style. Si vous avez ajouté une classe dans un composant, un hachage y sera ajouté et il sera unique pour votre composant et ne fuira nulle part. Mais que faire si vous avez besoin de styliser un composant enfant? Il est logique de lui donner un peu de classe et de prescrire des styles au parent. Ce problème est résolu assez simplement, en utilisant la directive : global ()


 <script> import Component from "./Component.svelte"; </script> <div class="parent"> <Component class="childClass" /> </div> <style> .parent :global(.childClass) { color: red; } </style> 

Exemple dans REPL


Avec cette approche, vous obtenez toujours un style isolé, mais cela s'applique à l'ensemble de la hiérarchie des composants enfants


3. Gestionnaires de tous les événements


Le composant Svelte doit prendre en charge l'événement afin qu'un gestionnaire externe puisse lui être affecté. Prescrire toutes les options pour les événements est fatigant. Au lieu de cela, vous pouvez écrire un gestionnaire universel qui recherchera les gestionnaires d'événements transmis au composant et les ajoutera à notre composant. J'ai repéré l' idée avec AlexxNB dans sa bibliothèque svelte-chota .


Exemple
 <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} /> 

Exemple dans REPL


Cette méthode n'est pas entièrement légale, car elle utilise l'API Svelte interne, qui peut changer. J'espère que dans le futur, le support de la directive on: * Issue sera ajouté sur github


4. Détection des emplacements


Si vous avez besoin de savoir si le contenu de la fente est transféré, je peux vous proposer deux options.


La première façon, juridique


Les emplacements ont un repli qui s'affiche si le contenu n'est pas transféré. Une fois le support pliant transformé en variable, nous pouvons détecter notre emplacement.


 <script> let footerRef = null; $: isFooterExists = Boolean(footerRef); </script> <slot name="footer"> <div bind:this={footerRef} /> </slot> {isFooterExists ? ' ' : ' '} 

La deuxième voie, semi-légale


Vous pouvez utiliser l'API Svelte interne


 const isFooterExists = Boolean($$props.$$slots && $$props.$$slots.footer); 

Exemple dans REPL


5. Portails


Svelte n'accepte pas les portails, comme dans React, mais c'est très simple à faire. Vous pouvez utiliser l'api DOM pour cela.


 <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> 

Pour monter le composant, nous le transférons sur le corps, et lors du retrait, nous supprimons notre portail.
Remarque importante: enveloppez votre portail dans une div, sinon Svelte risque de supprimer incorrectement des composants lors du démontage.


6. Animations


Svelte dispose d'un large éventail d'animations prêtes à l'emploi qui peuvent vous être utiles dans votre travail. Il est très facile d'animer l'apparition et la disparition de composants. Mais l'animation d'un bloc peut ralentir la suppression de la page entière. Svelte attendra la fin de l'animation avant de supprimer le composant de l'arborescence. Pour éviter cela, utilisez la directive locale .
Exemple de didacticiel


7. Emplacements et composants nommés


Malheureusement, vous ne pouvez pas transférer immédiatement un composant vers un emplacement nommé. Problème sur github


 <Component> <Child slot='footer'/> </Component> <!--    --> 

Pour transférer un composant vers un emplacement nommé, enveloppez-le dans un div ou dans toute autre balise html.


 <Component> <div slot='footer'> <Child /> </div> </Component> <!-- ! --> 

8. Obtenir une liste des propriétés des composants


Si vous avez besoin d'obtenir une liste de propriétés exportées à partir d'un composant, vous pouvez utiliser la construction suivante:


 <script> import Component from './Component.svelte'; const [_, ...props] = Object.getOwnPropertyNames(Component.prototype); </script> {JSON.stringify(props)} 

J'ai eu l' idée de PaulMaly .


9. Reliure double face


Après avoir évolué sur React, le concept de liaison bidirectionnelle semble intimidant, mais ce n'est qu'à première vue. Par conséquent, votre application sera plus concise et vous permettra de vous débarrasser d'un tas de gestionnaires. Vous pouvez utiliser à la fois une variable régulière et stocker en tant que stockage.


 <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} /> 

Exemple dans REPL


10. Contenu modifiable


Si vous devez rendre le contenu d'un élément modifiable, vous pouvez utiliser la directive contenteditable et lier les valeurs dans une variable.


 <script> let value = "Edit me"; </script> <div contenteditable="true" bind:textContent={value}>{value}</div> <div>Value: {value}</div> 

Exemple dans REPL


Taille des composants


Eh bien, et où sans React. Gardez une comparaison du nombre de lignes de code de composants sur Svelte et React, qui sont implémentées à peu près de la même manière. Le code et les styles sont pris en compte.



Bibliothèque de démonstration
Code source
Si vous trouvez un bug ou souhaitez suggérer quelque chose, créez un problème


PS
Le 22 février 2020 se tiendra le Svelte Russian Meetup # 1 à Moscou. Détails et annonce officielle dans le télégramme au groupe communautaire russe Svelte: @sveltejs


J'invite tout le monde à participer!

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


All Articles