Bygge interoperable nettkomponenter som til og med fungerer med React PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Bygge interoperable nettkomponenter som til og med fungerer med React

De av oss som har vært nettutviklere i mer enn noen år har sannsynligvis skrevet kode ved å bruke mer enn ett JavaScript-rammeverk. Med alle valgene der ute – React, Svelte, Vue, Angular, Solid – er det alt annet enn uunngåelig. En av de mer frustrerende tingene vi må forholde oss til når vi jobber på tvers av rammeverk, er å gjenskape alle disse lavnivå UI-komponentene: knapper, faner, rullegardinmenyene osv. Det som er spesielt frustrerende er at vi vanligvis vil ha dem definert i ett rammeverk. , si React, men må da skrive dem om hvis vi vil bygge noe i Svelte. Eller Vue. Eller Solid. Og så videre.

Ville det ikke vært bedre om vi kunne definere disse UI-komponentene på lavt nivå én gang, på en rammeagnostisk måte, og deretter gjenbruke dem mellom rammeverk? Selvfølgelig ville det det! Og vi kan; webkomponenter er veien. Dette innlegget vil vise deg hvordan.

Per nå mangler SSR-historien for webkomponenter litt. Declarative shadow DOM (DSD) er hvordan en webkomponent gjengis på serversiden, men når dette skrives, er den ikke integrert med dine favorittapplikasjonsrammeverk som Next, Remix eller SvelteKit. Hvis det er et krav for deg, sørg for å sjekke den siste statusen til DSD. Men ellers, hvis SSR ikke er noe du bruker, les videre.

Først litt kontekst

Webkomponenter er i hovedsak HTML-elementer som du definerer selv, som <yummy-pizza> eller hva som helst, fra grunnen av. De er dekket over alt her på CSS-Tricks (inkludert en omfattende serie av Caleb Williams og en av John Rhea), men vi vil kort gå gjennom prosessen. I hovedsak definerer du en JavaScript-klasse, arver den fra HTMLElement, og definer deretter hvilke egenskaper, attributter og stiler nettkomponenten har, og selvfølgelig markeringen den til slutt vil gi brukerne dine.

Å kunne definere tilpassede HTML-elementer som ikke er bundet til noen bestemt komponent er spennende. Men denne friheten er også en begrensning. Eksisterende uavhengig av et hvilket som helst JavaScript-rammeverk betyr at du egentlig ikke kan samhandle med disse JavaScript-rammeverket. Tenk på en React-komponent som henter noen data og deretter gjengir noen annen Reaksjonskomponent, sender dataene videre. Dette ville egentlig ikke fungere som en webkomponent, siden en webkomponent ikke vet hvordan en React-komponent skal gjengis.

Nettkomponenter utmerker seg spesielt som bladkomponenter. Bladkomponenter er det siste som skal gjengis i et komponenttre. Dette er komponentene som mottar noen rekvisitter, og gjengir noen UI. Disse er ikke komponentene som sitter i midten av komponenttreet ditt, sender data videre, setter kontekst osv. — bare rene deler av UI som vil se det samme ut, uansett hvilket JavaScript-rammeverk som driver resten av appen.

Nettkomponenten vi bygger

I stedet for å bygge noe kjedelig (og vanlig), som en knapp, la oss bygge noe litt annerledes. I min lasting innlegg vi så på å bruke uskarpe forhåndsvisninger for å forhindre innholdsflyt, og gi brukere et anstendig brukergrensesnitt mens bildene våre lastes inn. Vi så på base64 som koder for en uskarp, degradert versjon av bildene våre, og viser det i brukergrensesnittet mens det virkelige bildet ble lastet. Vi så også på å generere utrolig kompakte, uskarpe forhåndsvisninger ved å bruke et verktøy kalt Blurhash.

Det innlegget viste deg hvordan du genererer disse forhåndsvisningene og bruker dem i et React-prosjekt. Dette innlegget viser deg hvordan du bruker disse forhåndsvisningene fra en nettkomponent slik at de kan brukes av noen JavaScript-rammeverk.

Men vi må gå før vi kan løpe, så vi går gjennom noe trivielt og dumt først for å se nøyaktig hvordan webkomponenter fungerer.

Alt i dette innlegget vil bygge vanilje-webkomponenter uten verktøy. Det betyr at koden vil ha en del preg, men bør være relativt enkel å følge. Verktøy som Lit or stencil er designet for å bygge webkomponenter og kan brukes til å fjerne mye av denne kjeleplaten. Jeg oppfordrer deg til å sjekke dem ut! Men for dette innlegget vil jeg foretrekke litt mer preg i bytte mot å slippe å introdusere og lære bort en annen avhengighet.

En enkel tellerkomponent

La oss bygge den klassiske "Hello World" av JavaScript-komponenter: en teller. Vi gjengir en verdi og en knapp som øker denne verdien. Enkelt og kjedelig, men det lar oss se på den enklest mulige webkomponenten.

For å bygge en webkomponent er det første trinnet å lage en JavaScript-klasse, som arver fra HTMLElement:

class Counter extends HTMLElement {}

Det siste trinnet er å registrere webkomponenten, men bare hvis vi ikke har registrert den allerede:

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

Og, selvfølgelig, gjengi det:

<counter-wc></counter-wc>

Og alt i mellom er at vi får webkomponenten til å gjøre hva vi vil. En vanlig livssyklusmetode er connectedCallback, som utløses når nettkomponenten vår legges til DOM. Vi kan bruke den metoden til å gjengi det innholdet vi ønsker. Husk at dette er en JS-klasse som arver fra HTMLElement, som betyr vår this verdi er selve webkomponentelementet, med alle de vanlige DOM-manipulasjonsmetodene du allerede kjenner og elsker.

På det enkleste kan vi gjøre dette:

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

...som vil fungere helt fint.

Ordet "hei" i grønt.
Bygge interoperable nettkomponenter som til og med fungerer med React

Legger til ekte innhold

La oss legge til noe nyttig, interaktivt innhold. Vi trenger en <span> for å holde gjeldende tallverdi og en <button> for å øke telleren. Foreløpig vil vi lage dette innholdet i konstruktøren vår og legge det til når webkomponenten faktisk er i 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();
}

Hvis du virkelig blir oppslukt av den manuelle DOM-opprettingen, husk at du kan stille inn innerHTML, eller til og med opprette et malelement én gang som en statisk egenskap for webkomponentklassen din, klone den og sette inn innholdet for nye webkomponentforekomster. Det er sannsynligvis noen andre alternativer jeg ikke tenker på, eller du kan alltid bruke et nettkomponentrammeverk som Lit or stencil. Men for dette innlegget vil vi fortsette å holde det enkelt.

For å gå videre, trenger vi en innstillbar JavaScript-klasseeiendom som heter value

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

Det er bare en standardklasseeiendom med en setter, sammen med en annen egenskap for å holde verdien. En morsom vri er at jeg bruker den private JavaScript-klassens eiendomssyntaks for disse verdiene. Det betyr at ingen utenfor webkomponenten vår noen gang kan berøre disse verdiene. Dette er standard JavaScript som støttes i alle moderne nettlesere, så ikke vær redd for å bruke den.

Eller ring det gjerne _value hvis du foretrekker. Og til slutt vår update metode:

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

Det fungerer!

Tellerwebkomponenten.
Bygge interoperable nettkomponenter som til og med fungerer med React

Dette er åpenbart ikke kode du ønsker å opprettholde i stor skala. Her er en full arbeidseksempel hvis du vil se nærmere. Som jeg har sagt, er verktøy som Lit og Stencil designet for å gjøre dette enklere.

Legger til litt mer funksjonalitet

Dette innlegget er ikke et dypdykk i nettkomponenter. Vi vil ikke dekke alle APIer og livssykluser; vi vil ikke engang dekke skyggerøtter eller spor. Det er uendelig med innhold om disse emnene. Målet mitt her er å gi en grei nok introduksjon til å vekke litt interesse, sammen med noen nyttige veiledninger om faktisk ved hjelp av webkomponenter med de populære JavaScript-rammeverkene du allerede kjenner og elsker.

For det formål, la oss forbedre vår tellerwebkomponent litt. La oss få det til å akseptere en color attributt, for å kontrollere fargen på verdien som vises. Og la oss også få det til å akseptere en increment eiendom, slik at forbrukere av denne nettkomponenten kan øke den med 2, 3, 4 om gangen. Og for å drive disse tilstandsendringene, la oss bruke vår nye teller i en Svelte-sandkasse - vi kommer til React om litt.

Vi starter med den samme webkomponenten som før og legger til et fargeattributt. For å konfigurere nettkomponenten vår til å akseptere og svare på et attributt, legger vi til en statisk observedAttributes egenskap som returnerer attributtene som nettkomponenten vår lytter etter.

static observedAttributes = ["color"];

Med det på plass kan vi legge til en attributeChangedCallback livssyklusmetode, som vil kjøre når noen av attributtene er oppført i observedAttributes er innstilt eller oppdatert.

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

Nå oppdaterer vi vår update metode for å faktisk bruke det:

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

Til slutt, la oss legge til vår increment eiendom:

increment = 1;

Enkel og ydmyk.

Bruker telleverkskomponenten i Svelte

La oss bruke det vi nettopp har laget. Vi går inn i Svelte-appkomponenten vår og legger til noe som dette:

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

Og det fungerer! Telleren vår gjengir, øker, og rullegardinmenyen oppdaterer fargen. Som du kan se, gjengir vi fargeattributtet i Svelte-malen vår, og når verdien endres, håndterer Svelte benarbeidet med å ringe setAttribute på vår underliggende nettkomponentforekomst. Det er ikke noe spesielt her: dette er det samme det allerede gjør for egenskapene til noen HTML-element.

Ting blir litt interessant med increment rekvisitt. Dette er ikke et attributt på vår webkomponent; det er en rekvisitt på nettkomponentens klasse. Det betyr at den må settes på webkomponentens forekomst. Hold ut med meg, siden ting vil bli mye enklere om litt.

Først legger vi til noen variabler til Svelte-komponenten vår:

let increment = 1;
let wcInstance;

Vår kraftpakke med en tellerkomponent lar deg øke med 1 eller 2:

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

Men, i teorien, må vi få den faktiske forekomsten av webkomponenten vår. Dette er det samme vi alltid gjør når vi legger til en ref med React. Med Svelte er det enkelt bind:this direktiv:

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

Nå, i Svelte-malen vår, lytter vi etter endringer i komponentens inkrementvariabel og angir den underliggende webkomponentegenskapen.

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

Du kan teste det ut over på denne live-demoen.

Vi ønsker åpenbart ikke å gjøre dette for hver nettkomponent eller rekvisitt vi trenger å administrere. Hadde det ikke vært fint om vi bare kunne sette increment rett på nettkomponenten vår, i markup, som vi vanligvis gjør for komponentrekvisitter, og har det, du vet, bare arbeid? Med andre ord, det ville vært fint om vi kunne slette all bruk av wcInstance og bruk denne enklere koden i stedet:

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

Det viser seg at vi kan. Denne koden fungerer; Svelte håndterer alt det benarbeidet for oss. Sjekk det ut i denne demoen. Dette er standard oppførsel for stort sett alle JavaScript-rammeverk.

Så hvorfor viste jeg deg den manuelle måten å stille inn nettkomponentens rekvisitt på? To grunner: det er nyttig å forstå hvordan disse tingene fungerer, og for et øyeblikk siden sa jeg at dette fungerer for «ganske mye» alle JavaScript-rammer. Men det er ett rammeverk som, forferdelig nok, ikke støtter nettkomponentinnstilling som vi nettopp så.

React er et annet beist

Bygge interoperable nettkomponenter som til og med fungerer med React PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Bygge interoperable nettkomponenter som til og med fungerer med React

Reagere. Det mest populære JavaScript-rammeverket på planeten støtter ikke grunnleggende interoperasjon med nettkomponenter. Dette er et velkjent problem som er unikt for React. Interessant nok er dette faktisk fikset i Reacts eksperimentelle gren, men ble av en eller annen grunn ikke slått sammen til versjon 18. Når det er sagt, kan vi fortsatt spore fremdriften av det. Og du kan prøve dette selv med en live demo.

Løsningen er selvfølgelig å bruke en ref, ta tak i webkomponentforekomsten, og still inn manuelt increment når den verdien endres. Det ser slik ut:

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

Som vi diskuterte, er det rett og slett ikke skalerbart å kode dette manuelt for hver webkomponenteiendom. Men alt er ikke tapt fordi vi har et par alternativer.

Alternativ 1: Bruk attributter overalt

Vi har attributter. Hvis du klikket på React-demoen ovenfor, vil increment prop fungerte ikke, men fargen ble riktig endret. Kan vi ikke kode alt med attributter? Dessverre, nei. Attributtverdier kan bare være strenger. Det er bra nok her, og vi vil kunne komme noe langt med denne tilnærmingen. Tall som increment kan konverteres til og fra strenger. Vi kunne til og med JSON-strengifisere/analysere objekter. Men til slutt må vi overføre en funksjon til en webkomponent, og på det tidspunktet ville vi være tom for alternativer.

Alternativ 2: Pakk den inn

Det er et gammelt ordtak som sier at du kan løse ethvert problem innen informatikk ved å legge til et nivå av indirekte (bortsett fra problemet med for mange nivåer av indirektion). Koden for å sette disse rekvisittene er ganske forutsigbar og enkel. Hva om vi gjemmer det i et bibliotek? De smarte folkene bak Lit har én løsning. Dette biblioteket oppretter en ny React-komponent for deg etter at du har gitt den en webkomponent, og viser egenskapene den trenger. Selv om jeg er smart, er jeg ikke en fan av denne tilnærmingen.

I stedet for å ha en en-til-en-kartlegging av webkomponenter til manuelt opprettede React-komponenter, er det jeg foretrekker bare en Reager komponent som vi passerer vår web-komponent merke navn til (counter-wc i vårt tilfelle) – sammen med alle attributtene og egenskapene – og for at denne komponenten skal gjengi nettkomponenten vår, legg til ref, og finn ut hva som er en rekvisitt og hva som er en egenskap. Det er den ideelle løsningen etter min mening. Jeg vet ikke om et bibliotek som gjør dette, men det burde være enkelt å lage. La oss prøve det!

Dette er bruk vi ser etter:

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

wcTag er webkomponent-tag-navnet; resten er egenskapene og attributtene vi ønsker videreført.

Slik ser implementeringen min ut:

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

Den mest interessante linjen er på slutten:

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

Slik lager vi et element i React med et dynamisk navn. Faktisk er det dette React vanligvis transpilerer JSX til. Alle våre div er konvertert til createElement("div") samtaler. Vi trenger vanligvis ikke å kalle dette API direkte, men det er der når vi trenger det.

Utover det ønsker vi å kjøre en layouteffekt og gå gjennom hver rekvisitt som vi har sendt til komponenten vår. Vi går gjennom dem alle og sjekker om det er en eiendom med en in sjekk som sjekker webkomponentforekomstobjektet så vel som dets prototypekjede, som vil fange opp eventuelle gettere/settere som havner på klasseprototypen. Hvis ingen slik egenskap eksisterer, antas det å være et attributt. I begge tilfeller setter vi den bare hvis verdien faktisk har endret seg.

Hvis du lurer på hvorfor vi bruker useLayoutEffect istedenfor useEffect, det er fordi vi ønsker å kjøre disse oppdateringene umiddelbart før innholdet vårt gjengis. Vær også oppmerksom på at vi ikke har noen avhengighetsarray til vår useLayoutEffect; dette betyr at vi ønsker å kjøre denne oppdateringen på hver gjengivelse. Dette kan være risikabelt siden React har en tendens til å gjengi mye. Jeg forbedrer dette ved å pakke inn det hele React.memo. Dette er egentlig den moderne versjonen av React.PureComponent, som betyr at komponenten bare vil gjengis på nytt hvis noen av dens faktiske rekvisitter har endret seg - og den sjekker om det har skjedd via en enkel likhetssjekk.

Den eneste risikoen her er at hvis du sender en objektrekvisitt som du muterer direkte uten å tilordne på nytt, vil du ikke se oppdateringene. Men dette er sterkt motløs, spesielt i React-samfunnet, så jeg ville ikke bekymre meg for det.

Før jeg går videre, vil jeg si en siste ting. Du er kanskje ikke fornøyd med hvordan bruken ser ut. Igjen, denne komponenten brukes slik:

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

Spesielt kan det hende du ikke liker å overføre nettkomponent-taggen til <WcWrapper> komponent og foretrekker i stedet @lit-labs/react pakken ovenfor, som oppretter en ny individuell React-komponent for hver nettkomponent. Det er helt rettferdig, og jeg vil oppfordre deg til å bruke det du er mest komfortabel med. Men for meg er en fordel med denne tilnærmingen at det er enkelt å gjøre det slette. Hvis React ved et mirakel slår sammen riktig webkomponenthåndtering fra deres eksperimentelle gren til main i morgen vil du kunne endre koden ovenfor fra dette:

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

…til dette:

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

Du kan sannsynligvis til og med skrive en enkelt kodemod for å gjøre det overalt, og deretter slette <WcWrapper> totalt. Faktisk, skrape det: et globalt søk og erstatt med et RegEx vil sannsynligvis fungere.

Implementeringen

Jeg vet, det virker som det tok en reise å komme hit. Hvis du husker, var vårt opprinnelige mål å ta forhåndsvisningskoden vi så på i min lasting innlegg, og flytt den til en nettkomponent slik at den kan brukes i et hvilket som helst JavaScript-rammeverk. Reacts mangel på riktig interop la mye detaljer til blandingen. Men nå som vi har et anstendig grep om hvordan man lager en webkomponent, og bruker den, vil implementeringen nesten være antiklimaktisk.

Jeg slipper hele webkomponenten her og kaller ut noen av de interessante bitene. Hvis du vil se den i aksjon, her er en arbeider demo. Den vil veksle mellom mine tre favorittbøker på mine tre favorittprogrammeringsspråk. Nettadressen for hver bok vil være unik hver gang, slik at du kan se forhåndsvisningen, selv om du sannsynligvis vil strupe ting i DevTools Network-fanen for å virkelig se ting som skjer.

Se hele koden
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); }
}

Først registrerer vi attributtet vi er interessert i og reagerer når det endres:

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

Dette fører til at bildekomponenten vår opprettes, som bare vises når den er lastet inn:

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

Deretter har vi vår forhåndsvisningsegenskap, som enten kan være vår base64 forhåndsvisningsstreng, eller vår blurhash pakke:

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

Dette avhenger av hvilken hjelpefunksjon vi trenger:

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

Og til slutt vår render metode:

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

Og noen få hjelpemetoder for å binde alt sammen:

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

Det er litt mer overfladisk enn vi trenger hvis vi bygger dette i et rammeverk, men fordelen er at vi kan gjenbruke dette i hvilket som helst rammeverk vi vil – selv om React vil trenge en innpakning for nå, som vi diskuterte .

Odds og ender

Jeg har allerede nevnt Lits React-omslag. Men hvis du bruker Stencil, støtter den faktisk en separat utgangsrørledning kun for React. Og de gode folkene hos Microsoft har også laget noe som ligner på Lits omslag, knyttet til Fast web-komponentbiblioteket.

Som jeg nevnte, vil alle rammeverk som ikke heter React håndtere å sette webkomponentegenskaper for deg. Bare merk at noen har noen spesielle smaker av syntaks. For eksempel, med Solid.js, <your-wc value={12}> antar alltid det value er en eiendom, som du kan overstyre med en attr prefiks, som <your-wc attr:value={12}>.

Innpakning opp

Nettkomponenter er en interessant, ofte underbrukt del av webutviklingslandskapet. De kan bidra til å redusere avhengigheten din av et enkelt JavaScript-rammeverk ved å administrere brukergrensesnittet, eller «blad»-komponenter. Selv om det ikke vil være så ergonomisk å lage disse som nettkomponenter - i motsetning til Svelte- eller React-komponenter, er fordelen at de kan gjenbrukes mye.


Bygge interoperable nettkomponenter som til og med fungerer med React opprinnelig publisert på CSS-triks. Du burde få nyhetsbrevet.

Tidstempel:

Mer fra CSS triks