Construirea de componente web interoperabile care funcționează chiar și cu React PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Construirea de componente web interoperabile care funcționează chiar și cu React

Aceia dintre noi care am fost dezvoltatori web de mai mult de câțiva ani au scris probabil cod folosind mai mult de un cadru JavaScript. Cu toate opțiunile disponibile - React, Svelte, Vue, Angular, Solid - este aproape inevitabil. Unul dintre cele mai frustrante lucruri cu care trebuie să ne confruntăm atunci când lucrăm peste cadre este recrearea tuturor acelor componente ale interfeței de utilizare de nivel scăzut: butoane, file, meniuri derulante etc. Ceea ce este deosebit de frustrant este că, de obicei, le vom avea definite într-un singur cadru. , spune React, dar apoi trebuie să le rescriem dacă vrem să construim ceva în Svelte. Sau Vue. Sau Solid. Și așa mai departe.

Nu ar fi mai bine dacă am putea defini aceste componente UI de nivel scăzut o dată, într-un mod independent de cadru, și apoi să le reutilizam între cadre? Bineînțeles că ar fi! Și putem; componentele web sunt calea. Această postare vă va arăta cum.

De acum, povestea SSR pentru componentele web lipsește puțin. Declarative shadow DOM (DSD) este modul în care o componentă web este redată pe partea serverului, dar, din momentul în care scriem, nu este integrată cu cadrele de aplicație preferate, cum ar fi Next, Remix sau SvelteKit. Dacă aceasta este o cerință pentru dvs., asigurați-vă că verificați cea mai recentă stare a DSD. Dar în rest, dacă SSR nu este ceva ce utilizați, citiți mai departe.

În primul rând, un context

Componentele web sunt, în esență, elemente HTML pe care le definiți singur, cum ar fi <yummy-pizza> sau orice altceva, de la bază. Sunt acoperite peste tot aici la CSS-Tricks (inclusiv o serie extinsă de Caleb Williams și unul de John Rhea), dar vom parcurge pe scurt procesul. În esență, definiți o clasă JavaScript, de la care o moșteniți HTMLElement, apoi definiți orice proprietăți, atribute și stiluri pe care le are componenta web și, desigur, marcajul pe care îl va reda în cele din urmă utilizatorilor dvs.

Este interesant să fii capabil să definești elemente HTML personalizate care nu sunt legate de nicio componentă anume. Dar această libertate este și o limitare. Existența independentă de orice cadru JavaScript înseamnă că nu puteți interacționa cu adevărat cu acele cadre JavaScript. Gândiți-vă la o componentă React care preia unele date și apoi redă unele alte Componenta React, transmițând datele. Acest lucru nu ar funcționa cu adevărat ca o componentă web, deoarece o componentă web nu știe cum să redea o componentă React.

Componentele web excelează în special ca componentele frunzelor. Componentele frunzelor sunt ultimul lucru care poate fi redat într-un arbore de componente. Acestea sunt componentele care primesc unele elemente de recuzită și redă unele UI. Acestea sunt nu componentele care stau în mijlocul arborelui dvs. de componente, transmit date, setează context etc. - doar bucăți pure de UI care va arăta la fel, indiferent de cadru JavaScript care alimentează restul aplicației.

Componenta web pe care o construim

În loc să construim ceva plictisitor (și comun), cum ar fi un buton, să construim ceva puțin diferit. In al meu ultima postare Am analizat utilizarea previzualizărilor imaginilor neclare pentru a preveni refluarea conținutului și pentru a oferi utilizatorilor o interfață de utilizare decentă în timp ce imaginile noastre se încarcă. Ne-am uitat la codificarea base64 a versiunilor neclare și degradate ale imaginilor noastre și arătând asta în interfața noastră de utilizare în timp ce imaginea reală se încărca. De asemenea, ne-am uitat la generarea de previzualizări incredibil de compacte, neclare, folosind un instrument numit Blurhash.

Acea postare v-a arătat cum să generați acele previzualizări și să le utilizați într-un proiect React. Această postare vă va arăta cum să utilizați acele previzualizări dintr-o componentă web, astfel încât să poată fi utilizate de către Orice cadru JavaScript.

Dar trebuie să mergem înainte de a putea alerga, așa că mai întâi vom parcurge ceva banal și prostesc pentru a vedea exact cum funcționează componentele web.

Totul din această postare va construi componente web vanilla fără niciun instrument. Asta înseamnă că codul va avea un pic de boilerplate, dar ar trebui să fie relativ ușor de urmărit. Instrumente ca luminat or Șablon sunt concepute pentru construirea de componente ale rețelei și pot fi folosite pentru a îndepărta o mare parte din acest boilerplate. Vă îndemn să le verificați! Dar pentru această postare, voi prefera puțin mai mult boilerplate în schimbul că nu trebuie să introduc și să predau o altă dependență.

O componentă simplă de contor

Să construim clasicul „Hello World” al componentelor JavaScript: un contor. Vom reda o valoare și un buton care crește acea valoare. Simplu și plictisitor, dar ne va lăsa să ne uităm la cea mai simplă componentă web posibilă.

Pentru a construi o componentă web, primul pas este să creați o clasă JavaScript, care moștenește de la HTMLElement:

class Counter extends HTMLElement {}

Ultimul pas este să înregistrăm componenta web, dar numai dacă nu am înregistrat-o deja:

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

Și, desigur, redați-o:

<counter-wc></counter-wc>

Și totul între ele face ca componenta web să facă tot ce vrem. O metodă comună a ciclului de viață este connectedCallback, care se declanșează atunci când componenta noastră web este adăugată la DOM. Am putea folosi această metodă pentru a reda orice conținut dorim. Amintiți-vă, aceasta este o clasă JS de la care moștenește HTMLElement, ceea ce înseamnă al nostru this valoarea este elementul component web în sine, cu toate metodele normale de manipulare DOM pe care deja le cunoașteți și le iubiți.

Cel mai simplu, am putea face asta:

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

… care va funcționa bine.

Cuvântul „hei” în verde.
Construirea de componente web interoperabile care funcționează chiar și cu React

Adăugarea de conținut real

Să adăugăm niște conținut util, interactiv. Avem nevoie de <span> pentru a menține valoarea numărului curent și a <button> pentru a mări contorul. Pentru moment, vom crea acest conținut în constructorul nostru și îl vom adăuga atunci când componenta web este de fapt în 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();
}

Dacă sunteți cu adevărat dezamăgit de crearea manuală a DOM, amintiți-vă că puteți seta innerHTML, sau chiar creați un element șablon o dată ca proprietate statică a clasei dvs. de componente web, clonați-l și inserați conținutul pentru noile instanțe de componente web. Probabil că există și alte opțiuni la care nu mă gândesc, sau puteți utiliza întotdeauna un cadru de componentă web, cum ar fi luminat or Șablon. Dar pentru această postare, vom continua să o menținem simplă.

Mergând mai departe, avem nevoie de o proprietate de clasă JavaScript setabilă numită value

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

Este doar o proprietate de clasă standard cu un setter, împreună cu o a doua proprietate pentru a păstra valoarea. O întorsătură distractivă este că folosesc sintaxa proprietății de clasă JavaScript privată pentru aceste valori. Asta înseamnă că nimeni din afara componentei noastre web nu poate atinge aceste valori. Acesta este JavaScript standard care este acceptat în toate browserele moderne, așa că nu vă fie teamă să-l folosiți.

Sau nu ezitați să-l sunați _value daca preferi. Și, în sfârșit, al nostru update metodă:

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

Functioneaza!

Componenta web contor.
Construirea de componente web interoperabile care funcționează chiar și cu React

Evident, acesta nu este un cod pe care ați dori să-l mențineți la scară. Iată un plin exemplu de lucru dacă dorești o privire mai atentă. După cum am spus, instrumente precum Lit și Stencil sunt concepute pentru a face acest lucru mai simplu.

Adăugând mai multe funcționalități

Această postare nu este o scufundare profundă în componentele web. Nu vom acoperi toate API-urile și ciclurile de viață; nici nu vom acoperi rădăcini de umbră sau fante. Există conținut nesfârșit pe aceste subiecte. Scopul meu aici este să ofer o introducere suficient de decentă pentru a stârni un oarecare interes, împreună cu niște îndrumări utile despre de fapt folosind componente web cu cadrele JavaScript populare pe care deja le cunoașteți și le iubiți.

În acest scop, să îmbunătățim puțin componenta noastră de contor web. Să-l acceptăm a color atribut, pentru a controla culoarea valorii care este afișată. Și să-l punem să accepte un increment proprietate, astfel încât consumatorii acestei componente web o pot incrementa cu 2, 3, 4 la un moment dat. Și pentru a conduce aceste schimbări de stare, să folosim noul nostru contor într-un sandbox Svelte - vom ajunge la React în scurt timp.

Vom începe cu aceeași componentă web ca înainte și vom adăuga un atribut de culoare. Pentru a configura componenta noastră web să accepte și să răspundă la un atribut, adăugăm un static observedAttributes proprietate care returnează atributele pe care componenta noastră web le ascultă.

static observedAttributes = ["color"];

Cu asta în loc, putem adăuga un attributeChangedCallback metoda ciclului de viață, care va rula ori de câte ori oricare dintre atributele enumerate în observedAttributes sunt setate sau actualizate.

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

Acum ne actualizăm update metoda de a-l folosi efectiv:

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

În cele din urmă, să adăugăm noastre increment proprietate:

increment = 1;

Simplu și umil.

Folosind componenta contor în Svelte

Să folosim ceea ce tocmai am făcut. Vom intra în componenta aplicației noastre Svelte și vom adăuga ceva de genul acesta:

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

Și funcționează! Contorul nostru redă, crește, iar meniul drop-down actualizează culoarea. După cum puteți vedea, redăm atributul de culoare în șablonul nostru Svelte și, atunci când valoarea se schimbă, Svelte se ocupă de operațiunile de apelare. setAttribute pe instanța noastră de bază a componentei web. Nu este nimic special aici: acesta este același lucru pe care îl face deja pentru atributele lui Orice element HTML.

Lucrurile devin puțin interesante cu increment recuzită. Aceasta este nu un atribut pe componenta noastră web; este o recuzită în clasa componentei web. Aceasta înseamnă că trebuie setat pe instanța componentei web. Aveți grijă de mine, căci lucrurile vor deveni mult mai simple într-un pic.

Mai întâi, vom adăuga câteva variabile la componenta noastră Svelte:

let increment = 1;
let wcInstance;

Puterea noastră a unei componente de contor vă va permite să creșteți cu 1 sau cu 2:

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

Dar, teoretic, trebuie să obținem instanța reală a componentei noastre web. Acesta este același lucru pe care îl facem întotdeauna oricând adăugăm un ref cu React. Cu Svelte, e simplu bind:this directivă:

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

Acum, în șablonul nostru Svelte, ascultăm modificări ale variabilei de incrementare a componentei noastre și setăm proprietatea componentei web de bază.

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

Îl poți testa la acest demo live.

Evident, nu vrem să facem acest lucru pentru fiecare componentă web sau suport pe care trebuie să o gestionăm. N-ar fi frumos dacă am putea să ne punem increment chiar pe componenta noastră web, în ​​markup, așa cum facem în mod normal pentru elementele de recuzită ale componentelor, și o avem, știi, doar munca? Cu alte cuvinte, ar fi bine dacă am putea șterge toate utilizările wcInstance și folosiți în schimb acest cod mai simplu:

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

Se pare că putem. Acest cod funcționează; Svelte se ocupă de toată treaba asta pentru noi. Verificați-l în această demonstrație. Acesta este un comportament standard pentru aproape toate cadrele JavaScript.

Așadar, de ce ți-am arătat modul manual de a seta suportul componentei web? Două motive: este util să înțelegem cum funcționează aceste lucruri și, cu un moment în urmă, am spus că asta funcționează „mai mult” pentru toate cadrele JavaScript. Dar există un cadru care, înnebunitor, nu acceptă setarea elementelor web pentru componente, așa cum tocmai am văzut.

React este o fiară diferită

Construirea de componente web interoperabile care funcționează chiar și cu React PlatoBlockchain Data Intelligence. Căutare verticală. Ai.
Construirea de componente web interoperabile care funcționează chiar și cu React

Reacţiona. Cel mai popular cadru JavaScript de pe planetă nu acceptă interoperabilitatea de bază cu componentele web. Aceasta este o problemă binecunoscută care este unică pentru React. Interesant, acest lucru este de fapt rezolvat în ramura experimentală a lui React, dar din anumite motive nu a fost îmbinat în versiunea 18. Acestea fiind spuse, încă putem urmăriți progresul acesteia. Și poți încerca asta și tu cu un live demo.

Soluția, desigur, este folosirea unui ref, luați instanța componentei web și setați manual increment când acea valoare se schimbă. Arata cam asa:

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> );
}

După cum am discutat, codificarea manuală pentru fiecare proprietate de componentă web pur și simplu nu este scalabilă. Dar nu totul este pierdut pentru că avem câteva opțiuni.

Opțiunea 1: Folosiți atribute peste tot

Avem atribute. Dacă ați făcut clic pe demonstrația React de mai sus, increment recuzita nu funcționa, dar culoarea sa schimbat corect. Nu putem codifica totul cu atribute? Din pacate nu. Valorile atributelor pot fi doar șiruri. E destul de bun aici și am putea ajunge oarecum departe cu această abordare. Cifre ca increment pot fi convertite în și din șiruri. Am putea chiar și JSON să stringe/parse obiecte. Dar, în cele din urmă, va trebui să trecem o funcție într-o componentă web și, în acel moment, vom fi fără opțiuni.

Opțiunea 2: înfășurați-o

Există o veche zicală că poți rezolva orice problemă în informatică adăugând un nivel de indirectare (cu excepția problemei prea multor niveluri de indirectare). Codul pentru setarea acestor elemente de recuzită este destul de previzibil și simplu. Dacă îl ascundem într-o bibliotecă? Oamenii deștepți din spatele lui Lit au o singura solutie. Această bibliotecă creează o nouă componentă React pentru dvs. după ce îi oferiți o componentă web și enumerați proprietățile de care are nevoie. Deși sunt inteligent, nu sunt un fan al acestei abordări.

În loc să am o mapare unu-la-unu a componentelor web cu componentele React create manual, ceea ce prefer este doar unu Componenta React pe care o trecem componenta noastră web nume eticheta la (counter-wc în cazul nostru) - împreună cu toate atributele și proprietățile - și pentru ca această componentă să redea componenta noastră web, adăugați ref, apoi află ce este o recuzită și ce este un atribut. Aceasta este soluția ideală după părerea mea. Nu cunosc o bibliotecă care să facă asta, dar ar trebui să fie ușor de creat. Hai să încercăm!

Aceasta este folosire ne uităm după:

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

wcTag este numele etichetei componentei web; restul sunt proprietățile și atributele pe care vrem să le transmitem.

Iată cum arată implementarea mea:

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

Cea mai interesantă linie este la sfârșit:

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

Așa creăm un element în React cu un nume dinamic. De fapt, acesta este ceea ce React transpilează în mod normal JSX. Toate div-urile noastre sunt convertite în createElement("div") apeluri. În mod normal, nu trebuie să apelăm direct acest API, dar este acolo când avem nevoie de el.

Dincolo de asta, vrem să rulăm un efect de aspect și să trecem în buclă prin fiecare recuzită pe care am trecut-o la componenta noastră. Le parcurgem pe toate și verificăm dacă este o proprietate cu un in verificați că verifică obiectul instanței componentei web, precum și lanțul său de prototip, care va prinde orice getters/setters care ajung pe prototipul clasei. Dacă nu există o astfel de proprietate, se presupune că este un atribut. În ambele cazuri, îl setăm doar dacă valoarea sa schimbat efectiv.

Dacă vă întrebați de ce folosim useLayoutEffect în loc de useEffect, pentru că dorim să rulăm imediat aceste actualizări înainte ca conținutul nostru să fie redat. De asemenea, rețineți că nu avem nicio matrice de dependență față de nostru useLayoutEffect; aceasta înseamnă că vrem să rulăm această actualizare pe fiecare randare. Acest lucru poate fi riscant, deoarece React tinde să redea mult. Îmbunătățesc acest lucru prin înfășurarea întregului lucru React.memo. Aceasta este în esență versiunea modernă a React.PureComponent, ceea ce înseamnă că componenta se va reda numai dacă vreuna dintre elementele sale de recuzită reale s-a schimbat - și verifică dacă acest lucru s-a întâmplat printr-o simplă verificare a egalității.

Singurul risc aici este că, dacă treceți un obiect prop pe care îl mutați direct fără a-l reatribui, atunci nu veți vedea actualizările. Dar acest lucru este foarte descurajat, mai ales în comunitatea React, așa că nu mi-ar face griji.

Înainte de a trece mai departe, aș vrea să spun un ultim lucru. Este posibil să nu fiți mulțumit de modul în care arată utilizarea. Din nou, această componentă este utilizată astfel:

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

Mai exact, s-ar putea să nu vă place să transmiteți numele etichetei componentei web către <WcWrapper> componentă și preferă în schimb @lit-labs/react pachetul de mai sus, care creează o nouă componentă individuală React pentru fiecare componentă web. Este perfect corect și te-aș încuraja să folosești ceea ce ești cel mai confortabil. Dar pentru mine, un avantaj al acestei abordări este că este ușor de făcut șterge. Dacă printr-un miracol, React îmbină gestionarea corectă a componentelor web din ramura lor experimentală în main mâine, veți putea schimba codul de mai sus din acesta:

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

…la acest:

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

Probabil că ați putea chiar să scrieți un singur codemod pentru a face asta peste tot și apoi să ștergeți <WcWrapper> cu totul. De fapt, renunță la asta: probabil că o căutare globală și o înlocuire cu un RegEx ar funcționa.

Implementarea

Știu, se pare că a fost nevoie de o călătorie pentru a ajunge aici. Dacă vă amintiți, obiectivul nostru inițial a fost să luăm codul de previzualizare a imaginii pe care l-am uitat în mine ultima postareși mutați-l într-o componentă web, astfel încât să poată fi utilizat în orice cadru JavaScript. Lipsa de interoperabilitate adecvată a lui React a adăugat o mulțime de detalii mixului. Dar acum că avem o înțelegere decentă despre cum să creăm o componentă web și să o folosim, implementarea va fi aproape anti-climatică.

Voi renunța la întreaga componentă web aici și voi chema câteva dintre elementele interesante. Dacă doriți să-l vedeți în acțiune, iată a demonstrație de lucru. Va comuta între cele trei cărți preferate despre cele trei limbaje de programare preferate. Adresa URL pentru fiecare carte va fi unică de fiecare dată, astfel încât să puteți vedea previzualizarea, deși probabil veți dori să reduceți lucrurile în fila Rețea DevTools pentru a vedea cu adevărat lucrurile care au loc.

Vedeți întregul cod
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); }
}

În primul rând, înregistrăm atributul care ne interesează și reacționăm atunci când se modifică:

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

Acest lucru face ca componenta noastră imagine să fie creată, care se va afișa numai când este încărcată:

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

În continuare avem proprietatea noastră de previzualizare, care poate fi fie șirul nostru de previzualizare base64, fie blurhash pachet:

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

Aceasta se referă la orice funcție de ajutor de care avem nevoie:

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

Și, în sfârșit, al nostru render metodă:

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

Și câteva metode de ajutor pentru a lega totul:

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); }
}

Este puțin mai mult decât ne-ar trebui dacă construim acest lucru într-un cadru, dar avantajul este că îl putem reutiliza în orice cadru dorim - deși React va avea nevoie de un înveliș pentru moment, așa cum am discutat. .

Mărunţişuri

Am menționat deja ambalajul Lit's React. Dar dacă te trezești că folosești Stencil, acesta acceptă de fapt a conductă de ieșire separată doar pentru React. Și oamenii buni de la Microsoft au de asemenea a creat ceva asemănător cu ambalajul lui Lit, atașat la biblioteca de componente web Fast.

După cum am menționat, toate cadrele care nu sunt numite React se vor ocupa de setarea proprietăților componentelor web pentru dvs. Doar rețineți că unele au unele arome speciale de sintaxă. De exemplu, cu Solid.js, <your-wc value={12}> presupune întotdeauna că value este o proprietate, pe care o puteți înlocui cu un attr prefix, ca <your-wc attr:value={12}>.

La finalul

Componentele web sunt o parte interesantă, adesea subutilizată, a peisajului dezvoltării web. Ele vă pot ajuta să vă reduceți dependența de orice cadru JavaScript unic prin gestionarea componentelor UI sau „frunze”. În timp ce crearea acestora ca componente web - spre deosebire de componentele Svelte sau React - nu va fi la fel de ergonomică, avantajul este că vor fi reutilizabile pe scară largă.


Construirea de componente web interoperabile care funcționează chiar și cu React publicat inițial pe CSS-trucuri. Tu ar trebui primiți buletinul informativ.

Timestamp-ul:

Mai mult de la CSS Trucuri