Creazione di componenti Web interoperabili che funzionano anche con React PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Creazione di componenti Web interoperabili che funzionano anche con React

Quelli di noi che sono sviluppatori web da più di qualche anno hanno probabilmente scritto codice utilizzando più di un framework JavaScript. Con tutte le scelte là fuori - React, Svelte, Vue, Angular, Solid - è quasi inevitabile. Una delle cose più frustranti che dobbiamo affrontare quando lavoriamo tra framework è ricreare tutti quei componenti dell'interfaccia utente di basso livello: pulsanti, schede, menu a discesa, ecc. Ciò che è particolarmente frustrante è che in genere li avremo definiti in un framework , diciamo React, ma poi dobbiamo riscriverli se vogliamo costruire qualcosa in Svelte. O Vue. O Solido. E così via.

Non sarebbe meglio se potessimo definire questi componenti dell'interfaccia utente di basso livello una volta, in modo indipendente dal framework, e quindi riutilizzarli tra i framework? Certo che sarebbe! E possiamo; i componenti web sono la strada. Questo post ti mostrerà come.

A partire da ora, la storia dell'SSR per i componenti Web è un po' carente. Il DOM dichiarativo ombra (DSD) è il modo in cui un componente Web viene renderizzato lato server, ma, al momento della stesura di questo articolo, non è integrato con i tuoi framework applicativi preferiti come Next, Remix o SvelteKit. Se questo è un requisito per te, assicurati di controllare lo stato più recente di DSD. Ma altrimenti, se SSR non è qualcosa che stai usando, continua a leggere.

Innanzitutto, un po' di contesto

I componenti Web sono essenzialmente elementi HTML che definisci tu stesso, come <yummy-pizza> o qualsiasi altra cosa, da zero. Sono trattati dappertutto qui su CSS-Tricks (incluso una vasta serie di Caleb Williams ed uno di John Rea) ma illustreremo brevemente il processo. In sostanza, definisci una classe JavaScript, la eredi da HTMLElement, quindi definire le proprietà, gli attributi e gli stili del componente Web e, naturalmente, il markup che alla fine renderà agli utenti.

Essere in grado di definire elementi HTML personalizzati che non sono legati a nessun componente particolare è entusiasmante. Ma questa libertà è anche un limite. Esistere indipendentemente da qualsiasi framework JavaScript significa che non puoi davvero interagire con quei framework JavaScript. Pensa a un componente React che recupera alcuni dati e poi ne esegue il rendering Altro Componente Reagire, passando i dati. Questo non funzionerebbe davvero come componente Web, poiché un componente Web non sa come eseguire il rendering di un componente React.

I componenti Web eccellono particolarmente come componenti fogliari. Componenti fogliari sono l'ultima cosa da renderizzare in un albero dei componenti. Questi sono i componenti che ricevono alcuni oggetti di scena e ne rendono alcuni UI. Questi sono non i componenti che si trovano nel mezzo dell'albero dei componenti, che trasmettono dati, impostano il contesto, ecc. - solo puri pezzi di UI sembrerà lo stesso, indipendentemente dal framework JavaScript che alimenta il resto dell'app.

Il componente web che stiamo costruendo

Invece di creare qualcosa di noioso (e comune), come un pulsante, costruiamo qualcosa di leggermente diverso. Nel mio loading messaggio abbiamo esaminato l'utilizzo di anteprime di immagini sfocate per impedire il riflusso dei contenuti e fornire un'interfaccia utente decente per gli utenti durante il caricamento delle immagini. Abbiamo esaminato la codifica base64 di una versione sfocata e degradata delle nostre immagini e mostrandola nella nostra interfaccia utente mentre l'immagine reale veniva caricata. Abbiamo anche cercato di generare anteprime incredibilmente compatte e sfocate utilizzando uno strumento chiamato Sfocatura.

Quel post ti ha mostrato come generare quelle anteprime e usarle in un progetto React. Questo post ti mostrerà come utilizzare quelle anteprime da un componente Web in modo che possano essere utilizzate da in qualsiasi struttura JavaScript.

Ma dobbiamo camminare prima di poter correre, quindi analizzeremo prima qualcosa di banale e sciocco per vedere esattamente come funzionano i componenti web.

Tutto in questo post creerà componenti web vanilla senza alcuno strumento. Ciò significa che il codice avrà un po' di standard, ma dovrebbe essere relativamente facile da seguire. Strumenti come Lit or Stampino sono progettati per la costruzione di componenti web e possono essere utilizzati per rimuovere gran parte di questo boilerplate. Ti consiglio di dargli un'occhiata! Ma per questo post, preferirò un po' più standard in cambio di non dover introdurre e insegnare un'altra dipendenza.

Un semplice contatore componente

Costruiamo il classico “Hello World” dei componenti JavaScript: un contatore. Renderemo un valore e un pulsante che incrementi quel valore. Semplice e noioso, ma esamineremo il componente web più semplice possibile.

Per costruire un componente web, il primo passo è creare una classe JavaScript, che erediti da HTMLElement:

class Counter extends HTMLElement {}

L'ultimo passaggio consiste nel registrare il componente web, ma solo se non lo abbiamo già registrato:

if (!customElements.get("counter-wc")) { customElements.define("counter-wc", Counter);
}

E, naturalmente, renderla:

<counter-wc></counter-wc>

E tutto ciò che c'è in mezzo è fare in modo che il componente web faccia quello che vogliamo. Un metodo comune del ciclo di vita è connectedCallback, che si attiva quando il nostro componente web viene aggiunto al DOM. Potremmo usare quel metodo per rendere qualsiasi contenuto vorremmo. Ricorda, questa è una classe JS che eredita da HTMLElement, che significa il nostro this value è l'elemento del componente web stesso, con tutti i normali metodi di manipolazione DOM che già conosci e ami.

Al più semplice, potremmo fare questo:

class Counter extends HTMLElement { connectedCallback() { this.innerHTML = "<div style='color: green'>Hey</div>"; }
} if (!customElements.get("counter-wc")) { customElements.define("counter-wc", Counter);
}

... che funzionerà bene.

La parola "hey" in verde.
Creazione di componenti Web interoperabili che funzionano anche con React

Aggiunta di contenuti reali

Aggiungiamo alcuni contenuti utili e interattivi. Ci serve un <span> per mantenere il valore del numero corrente e a <button> per incrementare il contatore. Per ora, creeremo questo contenuto nel nostro costruttore e lo aggiungeremo quando il componente web è effettivamente nel DOM:

constructor() { super(); const container = document.createElement('div'); this.valSpan = document.createElement('span'); const increment = document.createElement('button'); increment.innerText = 'Increment'; increment.addEventListener('click', () => { this.#value = this.#currentValue + 1; }); container.appendChild(this.valSpan); container.appendChild(document.createElement('br')); container.appendChild(increment); this.container = container;
} connectedCallback() { this.appendChild(this.container); this.update();
}

Se sei davvero disgustato dalla creazione manuale del DOM, ricorda che puoi impostare innerHTMLo anche creare un elemento modello una volta come proprietà statica della classe del componente Web, clonarlo e inserire il contenuto per le nuove istanze del componente Web. Probabilmente ci sono altre opzioni a cui non sto pensando, oppure puoi sempre utilizzare un framework di componenti Web come Lit or Stampino. Ma per questo post, continueremo a mantenerlo semplice.

Andando avanti, abbiamo bisogno di una proprietà di classe JavaScript impostabile denominata value

#currentValue = 0; set #value(val) { this.#currentValue = val; this.update();
}

È solo una proprietà di classe standard con un setter, insieme a una seconda proprietà per contenere il valore. Una svolta divertente è che sto usando la sintassi della proprietà della classe JavaScript privata per questi valori. Ciò significa che nessuno al di fuori del nostro componente web potrà mai toccare questi valori. Questo è JavaScript standard che è supportato in tutti i browser moderni, quindi non aver paura di usarlo.

Oppure sentiti libero di chiamarlo _value se preferisci. E, infine, il nostro update Metodo:

update() { this.valSpan.innerText = this.#currentValue;
}

Funziona!

Il componente web del contatore.
Creazione di componenti Web interoperabili che funzionano anche con React

Ovviamente questo non è un codice che vorresti mantenere su larga scala. Ecco un completo esempio di lavoro se vuoi dare un'occhiata più da vicino. Come ho detto, strumenti come Lit e Stencil sono progettati per renderlo più semplice.

Aggiunta di alcune funzionalità in più

Questo post non è un'analisi approfondita dei componenti web. Non tratteremo tutte le API e i cicli di vita; non copriremo nemmeno radici d'ombra o fessure. Ci sono contenuti infiniti su questi argomenti. Il mio obiettivo qui è fornire un'introduzione abbastanza decente da suscitare un certo interesse, insieme ad alcune indicazioni utili su effettivamente utilizzando componenti web con i popolari framework JavaScript che già conosci e ami.

A tal fine, miglioriamo un po' il nostro componente web contatore. Facciamo in modo che accetti a color attributo, per controllare il colore del valore visualizzato. E facciamogli anche accettare un increment proprietà, in modo che i consumatori di questo componente Web possano incrementarlo di 2, 3, 4 alla volta. E per guidare questi cambiamenti di stato, utilizziamo il nostro nuovo contatore in una sandbox Svelte: tra poco arriveremo a Reagire.

Inizieremo con lo stesso componente Web di prima e aggiungeremo un attributo di colore. Per configurare il nostro componente Web in modo che accetti e risponda a un attributo, aggiungiamo un static observedAttributes proprietà che restituisce gli attributi che il nostro componente Web ascolta.

static observedAttributes = ["color"];

Con quello in atto, possiamo aggiungere a attributeChangedCallback metodo del ciclo di vita, che verrà eseguito ogni volta che uno qualsiasi degli attributi elencati in observedAttributes sono impostati o aggiornati.

attributeChangedCallback(name, oldValue, newValue) { if (name === "color") { this.update(); }
}

Ora aggiorniamo il nostro update metodo per usarlo effettivamente:

update() { this.valSpan.innerText = this._currentValue; this.valSpan.style.color = this.getAttribute("color") || "black";
}

Infine, aggiungiamo il nostro increment proprietà:

increment = 1;

Semplice e umile.

Utilizzando il componente contatore in Svelte

Usiamo quello che abbiamo appena fatto. Andremo nel nostro componente dell'app Svelte e aggiungeremo qualcosa del genere:

<script> let color = "red";
</script> <style> main { text-align: center; }
</style> <main> <select bind:value={color}> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select> <counter-wc color={color}></counter-wc>
</main>

E funziona! Il nostro contatore esegue il rendering, aumenta e il menu a discesa aggiorna il colore. Come puoi vedere, eseguiamo il rendering dell'attributo color nel nostro modello Svelte e, quando il valore cambia, Svelte gestisce il lavoro di chiamata setAttribute sulla nostra istanza del componente Web sottostante. Non c'è niente di speciale qui: questa è la stessa cosa che già fa per gli attributi di in qualsiasi Elemento HTML.

Le cose si fanno un po' interessanti con il increment puntello. Questo è non un attributo sul nostro componente web; è un supporto nella classe del componente web. Ciò significa che deve essere impostato sull'istanza del componente Web. Abbi pazienza, perché tra un po' le cose diventeranno molto più semplici.

Per prima cosa, aggiungeremo alcune variabili al nostro componente Svelte:

let increment = 1;
let wcInstance;

La nostra centrale elettrica di un componente contatore ti consentirà di incrementare di 1 o 2:

<button on:click={() => increment = 1}>Increment 1</button>
<button on:click={() => increment = 2}>Increment 2</button>

Ma, in teoria, dobbiamo ottenere l'istanza effettiva del nostro componente Web. Questa è la stessa cosa che facciamo sempre ogni volta che aggiungiamo a ref con Reagire. Con Svelte, è semplice bind:this direttiva:

<counter-wc bind:this={wcInstance} color={color}></counter-wc>

Ora, nel nostro modello Svelte, ascoltiamo le modifiche alla variabile di incremento del nostro componente e impostiamo la proprietà del componente Web sottostante.

$: { if (wcInstance) { wcInstance.increment = increment; }
}

Puoi provarlo oltre a questa demo dal vivo.

Ovviamente non vogliamo farlo per ogni componente web o prop che dobbiamo gestire. Non sarebbe bello se potessimo semplicemente impostare increment direttamente sul nostro componente web, nel markup, come facciamo normalmente per gli oggetti di scena dei componenti, e ce l'abbiamo, sai, solo lavoro? In altre parole, sarebbe bello se potessimo eliminare tutti gli usi di wcInstance e usa invece questo codice più semplice:

<counter-wc increment={increment} color={color}></counter-wc>

Si scopre che possiamo. Questo codice funziona; Svelte si occupa di tutto quel lavoro di gambe per noi. Dai un'occhiata in questa demo. Questo è un comportamento standard per quasi tutti i framework JavaScript.

Allora perché ti ho mostrato il modo manuale per impostare il prop del componente web? Due ragioni: è utile per capire come funzionano queste cose e, un momento fa, ho detto che funziona per “praticamente” tutti i framework JavaScript. Ma c'è un framework che, in modo esasperante, non supporta l'impostazione del componente prop come abbiamo appena visto.

Reagire è una bestia diversa

Creazione di componenti Web interoperabili che funzionano anche con React PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.
Creazione di componenti Web interoperabili che funzionano anche con React

Reagire. Il framework JavaScript più popolare al mondo non supporta l'interoperabilità di base con i componenti web. Questo è un problema ben noto che è unico per React. È interessante notare che questo è effettivamente risolto nel ramo sperimentale di React, ma per qualche motivo non è stato unito alla versione 18. Detto questo, possiamo ancora seguirne l'andamento. E puoi provarlo tu stesso con a demo live.

La soluzione, ovviamente, è usare a ref, prendi l'istanza del componente Web e imposta manualmente increment quando quel valore cambia. Si presenta così:

import React, { useState, useRef, useEffect } from 'react';
import './counter-wc'; export default function App() { const [increment, setIncrement] = useState(1); const [color, setColor] = useState('red'); const wcRef = useRef(null); useEffect(() => { wcRef.current.increment = increment; }, [increment]); return ( <div> <div className="increment-container"> <button onClick={() => setIncrement(1)}>Increment by 1</button> <button onClick={() => setIncrement(2)}>Increment by 2</button> </div> <select value={color} onChange={(e) => setColor(e.target.value)}> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select> <counter-wc ref={wcRef} increment={increment} color={color}></counter-wc> </div> );
}

Come abbiamo discusso, la codifica manuale di ogni proprietà del componente Web semplicemente non è scalabile. Ma non tutto è perduto perché abbiamo un paio di opzioni.

Opzione 1: usa gli attributi ovunque

Abbiamo attributi. Se hai fatto clic sulla demo React sopra, il file increment prop non funzionava, ma il colore è cambiato correttamente. Non possiamo codificare tutto con gli attributi? Purtroppo no. I valori degli attributi possono essere solo stringhe. Questo è abbastanza buono qui e saremmo in grado di andare un po' lontano con questo approccio. Numeri come increment può essere convertito in e da stringhe. Potremmo anche stringificare/parse JSON oggetti. Ma alla fine dovremo passare una funzione in un componente web ea quel punto saremmo senza opzioni.

Opzione 2: avvolgilo

C'è un vecchio detto secondo cui puoi risolvere qualsiasi problema in informatica aggiungendo un livello di indiretto (tranne il problema di troppi livelli di indiretto). Il codice per impostare questi oggetti di scena è piuttosto prevedibile e semplice. E se lo nascondessimo in una libreria? Le persone intelligenti dietro Lit avere una soluzione. Questa libreria crea un nuovo componente React per te dopo che gli hai assegnato un componente Web ed elenca le proprietà di cui ha bisogno. Sebbene intelligente, non sono un fan di questo approccio.

Piuttosto che avere una mappatura uno-a-uno dei componenti Web ai componenti React creati manualmente, quello che preferisco è solo prima Reagisci al componente che passiamo al nostro componente web nome dell'etichetta per (counter-wc nel nostro caso) — insieme a tutti gli attributi e le proprietà — e affinché questo componente visualizzi il nostro componente web, aggiungi il ref, quindi scopri cos'è un oggetto di scena e cos'è un attributo. Questa è la soluzione ideale secondo me. Non conosco una libreria che lo faccia, ma dovrebbe essere semplice da creare. Diamoci una possibilità!

Questa è la uso cercavano:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

wcTag è il nome del tag del componente Web; il resto sono le proprietà e gli attributi che vogliamo trasmettere.

Ecco come appare la mia implementazione:

import React, { createElement, useRef, useLayoutEffect, memo } from 'react'; const _WcWrapper = (props) => { const { wcTag, children, ...restProps } = props; const wcRef = useRef(null); useLayoutEffect(() => { const wc = wcRef.current; for (const [key, value] of Object.entries(restProps)) { if (key in wc) { if (wc[key] !== value) { wc[key] = value; } } else { if (wc.getAttribute(key) !== value) { wc.setAttribute(key, value); } } } }); return createElement(wcTag, { ref: wcRef });
}; export const WcWrapper = memo(_WcWrapper);

La riga più interessante è alla fine:

return createElement(wcTag, { ref: wcRef });

È così che creiamo un elemento in React con un nome dinamico. In effetti, questo è ciò in cui React traspare normalmente JSX. Tutti i nostri div vengono convertiti in createElement("div") chiamate. Normalmente non abbiamo bisogno di chiamare direttamente questa API, ma è lì quando ne abbiamo bisogno.

Oltre a ciò, vogliamo eseguire un effetto di layout e scorrere ogni oggetto che abbiamo passato al nostro componente. Li esaminiamo tutti e controlliamo se si tratta di una proprietà con an in check that controlla l'oggetto istanza del componente Web e la sua catena di prototipi, che catturerà tutti i getter/setter che finiscono sul prototipo della classe. Se tale proprietà non esiste, si presume che sia un attributo. In entrambi i casi, lo impostiamo solo se il valore è effettivamente cambiato.

Se ti stai chiedendo perché usiamo useLayoutEffect invece di useEffect, è perché vogliamo eseguire immediatamente questi aggiornamenti prima che il nostro contenuto venga visualizzato. Inoltre, nota che non abbiamo array di dipendenze per il nostro useLayoutEffect; questo significa che vogliamo eseguire questo aggiornamento ogni rendering. Questo può essere rischioso poiché React tende a rieseguire il rendering Un sacco. Lo miglioro avvolgendo il tutto React.memo. Questa è essenzialmente la versione moderna di React.PureComponent, il che significa che il componente eseguirà nuovamente il rendering se uno qualsiasi dei suoi oggetti di scena effettivi è cambiato e controlla se ciò è accaduto tramite un semplice controllo di uguaglianza.

L'unico rischio qui è che se stai passando un oggetto prop che stai mutando direttamente senza riassegnare, allora non vedrai gli aggiornamenti. Ma questo è altamente sconsigliato, specialmente nella comunità React, quindi non me ne preoccuperei.

Prima di andare avanti, vorrei richiamare un'ultima cosa. Potresti non essere soddisfatto di come appare l'utilizzo. Anche in questo caso, questo componente viene utilizzato in questo modo:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

In particolare, potrebbe non piacerti passare il nome del tag del componente web a <WcWrapper> componente e preferire invece il @lit-labs/react pacchetto sopra, che crea un nuovo singolo componente React per ogni componente web. È assolutamente giusto e ti incoraggerei a usare ciò con cui ti senti più a tuo agio. Ma per me, un vantaggio di questo approccio è che è facile delete. Se per qualche miracolo React unisce la corretta gestione dei componenti web dal loro ramo sperimentale in main domani, potresti cambiare il codice sopra da questo:

<WcWrapper wcTag="counter-wc" increment={increment} color={color} />

…a questa:

<counter-wc ref={wcRef} increment={increment} color={color} />

Probabilmente potresti anche scrivere un singolo codemod per farlo ovunque, quindi eliminare <WcWrapper> del tutto. In realtà, cancellalo: una ricerca globale e la sostituzione con una RegEx probabilmente funzionerebbero.

L'implemento

Lo so, sembra che ci sia voluto un viaggio per arrivare qui. Se ricordi, il nostro obiettivo originale era quello di prendere il codice di anteprima dell'immagine che abbiamo esaminato nel mio loading messaggioe spostalo in un componente Web in modo che possa essere utilizzato in qualsiasi framework JavaScript. La mancanza di un'adeguata interoperabilità di React ha aggiunto molti dettagli al mix. Ma ora che abbiamo una gestione decente su come creare un componente Web e utilizzarlo, l'implementazione sarà quasi deludente.

Lascerò cadere l'intero componente web qui e citerò alcuni dei bit interessanti. Se vuoi vederlo in azione, ecco a demo funzionante. Passerà tra i miei tre libri preferiti sui miei tre linguaggi di programmazione preferiti. L'URL di ogni libro sarà ogni volta univoco, quindi puoi vedere l'anteprima, anche se probabilmente vorrai limitare le cose nella scheda Rete di DevTools per vedere davvero le cose che stanno accadendo.

Visualizza l'intero codice
class BookCover extends HTMLElement { static observedAttributes = ['url']; attributeChangedCallback(name, oldValue, newValue) { if (name === 'url') { this.createMainImage(newValue); } } set preview(val) { this.previewEl = this.createPreview(val); this.render(); } createPreview(val) { if (typeof val === 'string') { return base64Preview(val); } else { return blurHashPreview(val); } } createMainImage(url) { this.loaded = false; const img = document.createElement('img'); img.alt = 'Book cover'; img.addEventListener('load', () =&gt; { if (img === this.imageEl) { this.loaded = true; this.render(); } }); img.src = url; this.imageEl = img; } connectedCallback() { this.render(); } render() { const elementMaybe = this.loaded ? this.imageEl : this.previewEl; syncSingleChild(this, elementMaybe); }
}

Innanzitutto, registriamo l'attributo che ci interessa e reagiamo quando cambia:

static observedAttributes = ['url']; attributeChangedCallback(name, oldValue, newValue) { if (name === 'url') { this.createMainImage(newValue); }
}

Questo fa sì che venga creato il nostro componente immagine, che verrà mostrato solo quando caricato:

createMainImage(url) { this.loaded = false; const img = document.createElement('img'); img.alt = 'Book cover'; img.addEventListener('load', () => { if (img === this.imageEl) { this.loaded = true; this.render(); } }); img.src = url; this.imageEl = img;
}

Successivamente abbiamo la nostra proprietà di anteprima, che può essere la nostra stringa di anteprima base64 o la nostra blurhash pacchetto:

set preview(val) { this.previewEl = this.createPreview(val); this.render();
} createPreview(val) { if (typeof val === 'string') { return base64Preview(val); } else { return blurHashPreview(val); }
}

Questo si riferisce a qualsiasi funzione di supporto di cui abbiamo bisogno:

function base64Preview(val) { const img = document.createElement('img'); img.src = val; return img;
} function blurHashPreview(preview) { const canvasEl = document.createElement('canvas'); const { w: width, h: height } = preview; canvasEl.width = width; canvasEl.height = height; const pixels = decode(preview.blurhash, width, height); const ctx = canvasEl.getContext('2d'); const imageData = ctx.createImageData(width, height); imageData.data.set(pixels); ctx.putImageData(imageData, 0, 0); return canvasEl;
}

E, infine, il nostro render Metodo:

connectedCallback() { this.render();
} render() { const elementMaybe = this.loaded ? this.imageEl : this.previewEl; syncSingleChild(this, elementMaybe);
}

E alcuni metodi di supporto per legare tutto insieme:

export function syncSingleChild(container, child) { const currentChild = container.firstElementChild; if (currentChild !== child) { clearContainer(container); if (child) { container.appendChild(child); } }
} export function clearContainer(el) { let child; while ((child = el.firstElementChild)) { el.removeChild(child); }
}

È un po' più standard di quanto ci servirebbe se lo costruissimo in un framework, ma il vantaggio è che possiamo riutilizzarlo in qualsiasi framework vorremmo, anche se React avrà bisogno di un wrapper per ora, come abbiamo discusso .

Cianfrusaglie

Ho già menzionato il wrapper di Lit's React. Ma se ti ritrovi a usare Stencil, in realtà supporta a pipeline di output separata solo per React. E anche le brave persone di Microsoft lo hanno fatto ha creato qualcosa di simile al wrapper di Lit, allegato alla libreria dei componenti Fast Web.

Come accennato, tutti i framework non denominati React gestiranno l'impostazione delle proprietà dei componenti Web per te. Nota solo che alcuni hanno alcuni tipi speciali di sintassi. Ad esempio, con Solid.js, <your-wc value={12}> lo presuppone sempre value è una proprietà, che puoi sovrascrivere con un attr prefisso, come <your-wc attr:value={12}>.

Concludendo

I componenti Web sono una parte interessante, spesso sottoutilizzata, del panorama dello sviluppo Web. Possono aiutare a ridurre la tua dipendenza da qualsiasi singolo framework JavaScript gestendo l'interfaccia utente o i componenti "foglia". Mentre la loro creazione come componenti web, al contrario dei componenti Svelte o React, non sarà così ergonomica, il vantaggio è che saranno ampiamente riutilizzabili.


Creazione di componenti Web interoperabili che funzionano anche con React originariamente pubblicato il CSS-Tricks. Dovresti ricevi la newsletter.

Timestamp:

Di più da Trucchi CSS