
Tendo experimentado o Svelte em projetos pessoais, eu queria seguir em frente e adotar uma estrutura maior no projeto. Para fazer isso, escrevi uma biblioteca de componentes átomos esbeltos . Como base, usei o kit de interface do usuário no React, que usamos no trabalho.
Que técnicas Svelte eu aprendi, leia sob o corte.
Este artigo pressupõe que você já esteja familiarizado com os conceitos básicos do Svelte. Caso contrário, recomendo que você leia meus artigos anteriores:
Vida cheia no Svelte
Desenvolvendo um jogo no Svelte 3
A biblioteca está na fase de revisão ativa. Alguns componentes ainda estão faltando, os problemas de acessibilidade não foram resolvidos e nem todos os erros foram corrigidos. Agora estou fazendo um projeto nesta baleia para entender no modo de combate o que precisa ser melhorado primeiro.
Então, o que aprendi escrevendo uma biblioteca de componentes no Svelte.
1. Usando a propriedade de classe
Se você deseja adicionar a propriedade de classe aos parâmetros do seu componente, receberá um erro, porque a palavra é reservada pelo próprio javascript.
<script> export let class = ''; </script>
Você pode resolver esse problema usando a API interna do Svelte. A variável $$ props contém todas as propriedades que são passadas para o componente. No componente pai, você pode passar a propriedade da classe
<Component class="someClass" />
E no próprio componente, defina a classe a partir da variável $$ props .
<div class={$$props.class} />
Exemplo no REPL
2. Componentes filho de estilo
Svelte usa isolamento de estilo. Se você adicionou uma classe a um componente, um hash será adicionado a ela e será exclusivo do seu componente e não vazará em nenhum lugar. Mas e se você precisar estilizar um componente filho? É lógico dar-lhe alguma classe e prescrever estilos nos pais. Esse problema é resolvido de maneira simples, usando a diretiva : global ()
<script> import Component from "./Component.svelte"; </script> <div class="parent"> <Component class="childClass" /> </div> <style> .parent :global(.childClass) { color: red; } </style>
Exemplo no REPL
Com essa abordagem, você ainda obtém um estilo isolado, mas isso se aplica a toda a hierarquia de componentes filhos
3. Manipuladores de todos os eventos
O componente Svelte deve suportar o evento para que um manipulador externo possa ser atribuído a ele. Prescrever todas as opções para eventos é cansativo. Em vez disso, você pode escrever um manipulador universal que procurará manipuladores de eventos que são passados para o componente e os adicionará ao nosso componente. Vi a ideia com AlexxNB em sua biblioteca de svelte-chota .
Exemplo <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} />
Exemplo no REPL
Esse método não é totalmente legal, porque usa a API Svelte interna, que pode ser alterada. Espero no futuro o suporte para a diretiva on: * Issue será adicionada no github
4. Detecção de Slot
Se você precisar descobrir se o conteúdo do slot foi transferido, posso oferecer duas opções.
A primeira maneira, legal
Os slots têm um fallback que é exibido se o conteúdo não for transferido. Tendo transformado o apoio dobrável em uma variável, podemos detectar nosso slot.
<script> let footerRef = null; $: isFooterExists = Boolean(footerRef); </script> <slot name="footer"> <div bind:this={footerRef} /> </slot> {isFooterExists ? ' ' : ' '}
A segunda maneira, semi-legal
Você pode usar a API interna Svelte
const isFooterExists = Boolean($$props.$$slots && $$props.$$slots.footer);
Exemplo no REPL
5. Portais
O Svelte não aceita portais, como no React, mas é muito simples de fazer. Você pode usar a API do DOM para isso.
<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>
Para montar o componente, transferimos para o corpo e, ao remover, removemos nosso portal.
Nota importante: envolva seu portal em uma div, caso contrário, o Svelte poderá remover componentes incorretamente ao desmontar.
6. Animações
O Svelte possui um grande conjunto de animações prontas que podem ser úteis para você em seu trabalho. É muito fácil animar a aparência e o desaparecimento de componentes. Mas animar um bloco pode retardar a exclusão de toda a página. O Svelte aguardará a conclusão da animação antes de remover o componente da árvore. Para evitar isso, use a diretiva local .
Exemplo de tutorial
7. Slots e componentes nomeados
Infelizmente, você não pode transferir um componente para um slot nomeado imediatamente. Problema no github
<Component> <Child slot='footer'/> </Component>
Para transferir um componente para um slot nomeado, envolva-o em uma div ou em qualquer outra tag html.
<Component> <div slot='footer'> <Child /> </div> </Component>
8. Obtendo uma lista de propriedades do componente
Se você precisar obter uma lista de propriedades que são exportadas de um componente, poderá usar a seguinte construção:
<script> import Component from './Component.svelte'; const [_, ...props] = Object.getOwnPropertyNames(Component.prototype); </script> {JSON.stringify(props)}
Eu recebi a ideia de PaulMaly .
9. Encadernação frente e verso
Depois de desenvolver o React, o conceito de ligação bidirecional parece intimidador, mas é apenas à primeira vista. Como resultado, seu aplicativo parecerá mais conciso e permitirá que você se livre de vários manipuladores. Você pode usar uma variável regular e armazenar como armazenamento.
<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} />
Exemplo no REPL
10. Conteúdo editável
Se você precisar tornar o conteúdo de um elemento editável, poderá usar a diretiva contenteditable e vincular os valores a uma variável.
<script> let value = "Edit me"; </script> <div contenteditable="true" bind:textContent={value}>{value}</div> <div>Value: {value}</div>
Exemplo no REPL
Tamanho do componente
Bem, e onde sem reagir. Mantenha uma comparação do número de linhas de código de componentes no Svelte e no React, que são implementadas aproximadamente da mesma forma. Código e estilos são levados em consideração.

Biblioteca de demonstração
Código fonte
Se você encontrar um bug ou quiser sugerir algo, crie um problema
PS
22 de fevereiro de 2020 será realizado o Svelte Russian Meetup # 1 em Moscou. Detalhes e anúncio oficial no telegrama ao grupo comunitário russo Svelte: @sveltejs
Convido todos a participar!