Diejenigen von uns, die mehr als ein paar Jahre Webentwickler waren, haben wahrscheinlich Code mit mehr als einem JavaScript -Framework geschrieben. Mit all den Auswahlm?glichkeiten - reagieren, Sufle, Vue, Angular, Solid - es ist so gut wie unvermeidlich. Eines der frustrierenderen Dinge, mit denen wir uns bei der Arbeit in Frameworks befassen müssen, ist die Wiederherstellung all dieser UI-Komponenten auf niedriger Ebene: Schaltfl?chen, Registerkarten, Dropdowns usw. Besonders frustrierend ist, dass wir sie normalerweise in einem Framework definiert haben, sagen wir, reagieren, aber müssen sie dann neu schreiben, wenn wir etwas in Svelte bauen wollen. Oder Vue. Oder fest. Und so weiter.
W?re es nicht besser, wenn wir diese UI-Komponenten auf niedriger Ebene einmal auf eine agnostische Weise definieren und sie dann zwischen Frameworks wiederverwenden k?nnten? Natürlich würde es! Und wir k?nnen; Webkomponenten sind der Weg. Dieser Beitrag zeigt Ihnen wie.
Ab sofort fehlt die SSR -Geschichte für Webkomponenten. Declarative Shadow DOM (DSD) ist, wie eine Webkomponente serverseitig gerendert wird, aber nach diesem Schreiben wird sie jedoch nicht in Ihre bevorzugten Anwendungsframeworks wie Next, Remix oder Sveltekit integriert. Wenn dies eine Voraussetzung für Sie ist, überprüfen Sie unbedingt den neuesten Status von DSD. Aber ansonsten, wenn SSR nicht etwas nicht verwendet, lesen Sie weiter.
Erstens ein Kontext
Webkomponenten sind im Wesentlichen HTML-Elemente, die Sie selbst definieren, wie
Es ist aufregend, benutzerdefinierte HTML -Elemente zu definieren, die nicht an eine bestimmte Komponente gebunden sind. Diese Freiheit ist aber auch eine Einschr?nkung. Wenn Sie unabh?ngig von einem JavaScript -Framework existieren, k?nnen Sie nicht wirklich mit diesen JavaScript -Frameworks interagieren. Stellen Sie sich eine React -Komponente vor, die einige Daten abruft und dann eine andere React -Komponente macht und die Daten weitergibt. Dies würde nicht wirklich als Webkomponente funktionieren, da eine Webkomponente nicht wei?, wie man eine React -Komponente rendert.
Webkomponenten sind besonders als Blattkomponenten ausgestattet. Blattkomponenten sind das Letzte, was in einem Komponentenbaum gerendert werden kann. Dies sind die Komponenten, die einige Requisiten erhalten und eine Benutzeroberfl?che rendern. Dies sind nicht die Komponenten, die in der Mitte Ihres Komponentenbaums sitzen, Daten übergeben, Kontext einstellen usw. - nur reine UI -Teile, die gleich aussehen, unabh?ngig davon, welches JavaScript -Framework den Rest der App mit Strom versorgt.
Die Webkomponente, die wir bauen
Anstatt etwas Langweiliges (und Gemeinsames) zu bauen, wie ein Knopf, bauen wir etwas anderes auf. In meinem letzten Beitrag befassten wir uns mit der Verwendung von verschwommenen Bildvoransichten, um den Inhaltsausfall zu verhindern, und bieten eine anst?ndige Benutzeroberfl?che für Benutzer, w?hrend unsere Bilder laden. Wir haben uns Base64 angesehen, um eine verschwommene, degradierte Version unserer Bilder zu kodieren und dies in unserer Benutzeroberfl?che zu zeigen, w?hrend das reale Bild geladen wurde. Wir haben uns auch mithilfe eines Tools namens Blurhash unglaublich kompakte, verschwommene Vorschau angesehen.
Dieser Beitrag hat Ihnen gezeigt, wie Sie diese Voransichten generieren und in einem React -Projekt verwenden k?nnen. In diesem Beitrag werden Sie angezeigt, wie Sie diese Voransichten aus einer Webkomponente verwenden, damit sie von jedem JavaScript -Framework verwendet werden k?nnen.
Aber wir müssen gehen, bevor wir rennen k?nnen, also werden wir zuerst etwas Triviales und Dummes durchgehen, um genau zu sehen, wie Webkomponenten funktionieren.
Alles in diesem Beitrag erstellt Vanilla -Webkomponenten ohne Werkzeuge. Das bedeutet, dass der Code ein bisschen Kesselplatte hat, sollte jedoch relativ einfach zu befolgen sein. Tools wie Lit oder Schablone sind zum Erstellen von Webkomponenten konzipiert und k?nnen zum Entfernen eines Gro?teils dieser Kesselplatte verwendet werden. Ich fordere Sie auf, sie zu überprüfen! Aber für diesen Beitrag werde ich etwas mehr Kesselplatte bevorzugen, um keine andere Abh?ngigkeit vorzustellen und zu lehren.
Eine einfache Gegenkomponente
Erstellen wir die klassische ?Hello World“ von JavaScript -Komponenten: eine Theke. Wir werden einen Wert und eine Schaltfl?che rendern, die diesen Wert erh?ht. Einfach und langweilig, aber es l?sst uns die einfachste Webkomponente ansehen.
Um eine Webkomponente zu erstellen, besteht der erste Schritt darin, eine JavaScript -Klasse zu erstellen, die von htmlelement ererbt:
Der Klassenz?hler erweitert Htmlelement {}
Der letzte Schritt besteht darin, die Webkomponente zu registrieren, aber nur, wenn wir sie noch nicht registriert haben:
if (! CustomElements.get ("Counter-WC")) { CustomElements.define ("Counter-WC", The Counter); }
Und natürlich rendern es:
<counter-wc> </counter-wc>
Und alles dazwischen ist, dass wir die Webkomponente tun, was wir wollen. Eine übliche Lebenszyklusmethode ist ConnectedCallback, die ausfeuert, wenn unsere Webkomponente zum DOM hinzugefügt wird. Wir k?nnten diese Methode verwenden, um alle Inhalte zu rendern, die wir m?chten. Denken Sie daran, dass dies eine JS -Klasse ist, die von HTMLElement erbt, was bedeutet, dass unser Wert das Webkomponentenelement selbst ist, mit all den normalen DOM -Manipulationsmethoden, die Sie bereits kennen und lieben.
Am einfachsten k?nnten wir Folgendes tun:
Der Klassenz?hler erweitert Htmlelement { connectedCallback () { this.innerhtml = "<div style="'color:" green> hey </div>"; } } if (! CustomElements.get ("Counter-WC")) { CustomElements.define ("Counter-WC", The Counter); }
… Was wird gut funktionieren.
Hinzufügen von echten Inhalten
Fügen wir einige nützliche, interaktive Inhalte hinzu. Wir brauchen eine , um den aktuellen Zahlenwert und eine
constructor () { super(); const container = document.createelement ('div'); this.valspan = document.createelement ('span'); const increment = document.createelement ('button'); Increment.InNerText = 'Increment'; increment.adDeVentListener ('klick', () => { this.#value = this.#currentValue 1; }); Container.AppendChild (this.valpan); Container.AppendChild (document.Createelement ('br')); Container.AppendChild (Inkrement); this.container = Container; } connectedCallback () { this.appendChild (this.container); this.update (); }
Wenn Sie sich von der manuellen DOM -Erstellung wirklich ausgedacht haben, denken Sie daran, dass Sie Innerhtml festlegen oder sogar ein Vorlagenelement als statische Eigenschaft Ihrer Web -Komponentenklasse erstellen, ihn klonen und den Inhalt für neue Webkomponenteninstanzen einfügen k?nnen. Es gibt wahrscheinlich einige andere Optionen, an die ich nicht denke, oder Sie k?nnen immer ein Webkomponenten -Framework wie Lit oder Schablone verwenden. Aber für diesen Beitrag werden wir es weiterhin einfach halten.
Wenn wir weitermachen, brauchen wir eine einsetzbare Eigenschaft der JavaScript -Klasse mit dem Namen Value
#CurrentValue = 0; Setzen Sie #Value (Val) { Dies.#currentValue = val; this.update (); }
Es ist nur eine Standard -Klasseneigenschaft mit einem Setter, zusammen mit einer zweiten Eigenschaft, um den Wert zu halten. Eine lustige Wendung ist, dass ich die Eigenschaftssyntax der privaten JavaScript -Klasse für diese Werte verwende. Das bedeutet, dass niemand au?erhalb unserer Webkomponente diese Werte jemals berühren kann. Dies ist Standard -JavaScript, das in allen modernen Browsern unterstützt wird. Haben Sie also keine Angst, es zu verwenden.
Oder nennen Sie es _Value, wenn Sie es vorziehen. Und schlie?lich unsere Update -Methode:
aktualisieren() { this.valspan.inNertext = this.#currentValue; }
Es funktioniert!
Offensichtlich ist dies kein Code, den Sie im Ma?stab beibehalten m?chten. Hier ist ein komplettes Beispiel, wenn Sie einen genaueren Blick m?chten. Wie ich bereits sagte, sind Tools wie Lit und Schablone so gestaltet, dass sie dies einfacher machen.
Etwas mehr Funktionalit?t hinzufügen
Dieser Beitrag ist kein tiefes Eintauchen in Webkomponenten. Wir werden nicht alle APIs und Lebenszyklen abdecken. Wir werden nicht einmal Schattenwurzeln oder Slots abdecken. Es gibt endlose Inhalte zu diesen Themen. Mein Ziel hier ist es, eine anst?ndige Einführung zu bieten, um ein gewisses Interesse zu wecken, zusammen mit einigen nützlichen Anleitungen zur tats?chlichen Verwendung von Webkomponenten mit den beliebten JavaScript -Frameworks, die Sie bereits kennen und lieben.
Lassen Sie uns zu diesem Zweck unsere Counter -Webkomponente ein wenig verbessern. Lassen Sie es uns ein Farbattribut akzeptieren, um die Farbe des angezeigten Werts zu steuern. Lassen Sie uns auch eine Increment -Eigenschaft akzeptieren, sodass die Verbraucher dieser Webkomponente sie jeweils um 2, 3, 4 erh?hen k?nnen. Um diese Zustands?nderungen voranzutreiben, verwenden wir unseren neuen Z?hler in einer schlanken Sandkiste - wir werden ein wenig reagieren.
Wir beginnen mit derselben Webkomponente wie zuvor und fügen ein Farbattribut hinzu. Um unsere Webkomponente so zu konfigurieren, um ein Attribut zu akzeptieren und darauf zu reagieren, fügen wir eine statische Eigenschaft beobachtete Eigenschaft hinzu, die die Attribute zurückgibt, für die unsere Webkomponente h?rt.
static beobachteteAttributes = ["Farbe"];
Mit diesem vorhanden k?nnen wir eine AttributechangeDcallback -Lebenszyklusmethode hinzufügen, die ausgeführt wird, wenn eine der in beobachteten ATTRIBUTes aufgeführten Attribute festgelegt oder aktualisiert wird.
AttributEchangedCallback (Name, OldValue, NewValue) { if (name === "Farbe") { this.update (); } }
Jetzt aktualisieren wir unsere Update -Methode, um sie tats?chlich zu verwenden:
aktualisieren() { this.valspan.Innertext = this._currentValue; this.valspan.style.color = this.getAttribute ("Farbe") || "Schwarz"; }
Zuletzt fügen wir unsere Increment -Eigenschaft hinzu:
Inkrement = 1;
Einfach und bescheiden.
Verwenden der Z?hlerkomponente in Svelte
Lassen Sie uns das verwenden, was wir gerade gemacht haben. Wir werden in unsere Sufle -App -Komponente gehen und so etwas hinzufügen:
<script> lass color = "rot"; </script> <styles> haupts?chlich { Text-Align: Mitte; } <main> <select bind: value="{color}"> <option value="rot"> rot </option> <option value="Green"> Green </option> <option value="Blue"> Blue </option> </select> <counter wc color="{color}"> </counter></main></styles>
Und es funktioniert! Unsere Z?hler rendern, Inkremente und die Dropdown -Rendite aktualisieren die Farbe. Wie Sie sehen k?nnen, rendern wir das Farbattribut in unserer schlanken Vorlage und wenn sich der Wert ?ndert, übernimmt Svelte das Beinwerk, SetAttribute auf unserer zugrunde liegenden Webkomponenteninstanz aufzurufen. Hier gibt es nichts Besonderes: Dies ist das gleiche, was es für die Attribute eines HTML -Elements bereits tut.
Die Dinge werden mit der Increment -Requisite ein bisschen interessant. Dies ist kein Attribut in unserer Webkomponente. Es ist eine Requisite in der Klasse der Webkomponente. Das bedeutet, dass es in der Instanz der Webkomponente festgelegt werden muss. Tragen Sie mit mir, da die Dinge ein wenig viel einfacher werden.
Zun?chst fügen wir unserer schlanken Komponente einige Variablen hinzu:
Sei inkrement = 1; lass wcinstance;
In unserem Kraftpaket einer Z?hlerkomponente k?nnen Sie um 1 oder 2 erh?ht werden:
<schaltfl auf: klick="{()"> inkrement = 1}> inkrement 1 <schaltfl auf: klick="{()"> inkrement = 2}> inkrement 2 </schaltfl></schaltfl>
Theoretisch müssen wir jedoch die tats?chliche Instanz unserer Webkomponente erhalten. Dies ist dasselbe, was wir immer tun, wenn wir einen Schiedsrichter mit React hinzufügen. Mit Sufle ist es eine einfache Bindung: diese Richtlinie:
<counter-wc bind: this="{wcinstance}" color="{color}"> </counter-wc>
In unserer schlanken Vorlage h?ren wir nun auf ?nderungen an der Inkrementvariablen unserer Komponente und setzen die zugrunde liegende Webkomponenteneigenschaft.
$: { if (wcinstance) { wcinstance.increment = Increment; } }
Sie k?nnen es bei dieser Live -Demo testen.
Wir m?chten dies offensichtlich nicht für jede Webkomponente oder Requiente tun, die wir verwalten müssen. W?re es nicht sch?n, wenn wir in Markup, wie wir es normalerweise für Komponenten -Requisiten tun, nur das Inkrement in unserer Webkomponente einstellen und sie, wissen Sie, einfach nur für die Arbeit haben? Mit anderen Worten, es w?re sch?n, wenn wir alle Verwendungen von WCInstance l?schen und stattdessen diesen einfacheren Code verwenden k?nnten:
<counter-wc increment="{increment}" color="{color}"> </counter-wc>
Es stellt sich heraus, dass wir k?nnen. Dieser Code funktioniert; Svelte kümmert sich um all diese Beinarbeit für uns. Probieren Sie es in dieser Demo aus. Dies ist ein Standardverhalten für so ziemlich alle JavaScript -Frameworks.
Warum habe ich Ihnen die manuelle M?glichkeit zum Festlegen der Requisite der Webkomponente gezeigt? Zwei Gründe: Es ist nützlich zu verstehen, wie diese Dinge funktionieren, und vor einem Moment sagte ich, dass dies für ?so ziemlich“ alle JavaScript -Frameworks funktioniert. Es gibt jedoch einen Framework, der, wie wir gerade gesehen haben, nicht unterstützt.
React ist ein anderes Tier
Reagieren. Das beliebteste JavaScript -Framework auf dem Planeten unterstützt keine grundlegende Interop -Interop mit Webkomponenten. Dies ist ein bekanntes Problem, das einzigartig für Reaktionen ist. Interessanterweise wird dies tats?chlich in Reacts experimentellem Zweig festgelegt, aber aus irgendeinem Grund wurde nicht in Version 18 zusammengeführt. Das hei?t, wir k?nnen den Fortschritt immer noch verfolgen. Und Sie k?nnen dies selbst mit einer Live -Demo ausprobieren.
Die L?sung besteht natürlich darin, einen Ref zu verwenden, die Webkomponenteninstanz zu greifen und in Erkrankungen zu steigern, wenn sich dieser Wert ?ndert. Es sieht so aus:
React, {usestate, useref, useEffect} aus 'react'; Import './Counter-Wc'; Exportieren Sie Standardfunktionsfunktion app () { const [Increment, setIncrement] = usustate (1); const [color, setColor] = usustate ('rot'); const wcref = useref (null); useEffect (() => { wcref.current.increment = Increment; }, [Inkrement]); zurückkehren ( <div> <div classname="Increment-Container"> <button onclick="{()"> setIncrement (1)}> Inkrement nach 1 </button> <button onclick="{()"> setIncrement (2)}> Inkrement nach 2 </button> </div> <select value="{color}" onchange="{(e)"> setColor (e.target.Value)}> <option value="rot"> rot </option> <option value="Green"> Green </option> <option value="Blue"> Blue </option> </select> <counter wc ref="{wcref}" increment="{increment}" color="{color}"> </counter> </div> ); }Live -Demo
Wie wir besprochen haben, ist es einfach nicht skalierbar, dies manuell für jede Webkomponenteneigenschaft zu kodieren. Aber alles ist nicht verloren, weil wir ein paar Optionen haben.
Option 1: Verwenden Sie überall Attribute
Wir haben Attribute. Wenn Sie oben auf die React -Demo geklickt haben, funktionierte die Increment -Requisite nicht, aber die Farbe hat sich korrekt ge?ndert. K?nnen wir nicht alles mit Attributen codieren? Leider nein. Attributwerte k?nnen nur Zeichenfolgen sein. Das ist hier gut genug und wir k?nnten mit diesem Ansatz etwas weit kommen. Zahlen wie Inkrement k?nnen zu und von Strings konvertiert werden. Wir k?nnten sogar Objekte JSON Stringify/analysieren. Aber irgendwann müssen wir eine Funktion in eine Webkomponente übergeben, und zu diesem Zeitpunkt w?ren wir keine Optionen mehr.
Option 2: Wickeln Sie es ein
Es gibt ein altes Sprichwort, dass Sie jedes Problem in der Informatik l?sen k?nnen, indem Sie ein Ma? an Indirektion hinzufügen (mit Ausnahme des Problems zu vieler Indirektion). Der Code zum Festlegen dieser Requisiten ist ziemlich vorhersehbar und einfach. Was ist, wenn wir es in einer Bibliothek verstecken? Die klugen Leute hinter Lit haben eine L?sung. Diese Bibliothek erstellt eine neue React -Komponente für Sie, nachdem Sie ihr eine Webkomponente gegeben haben, und listen Sie die Eigenschaften auf, die sie ben?tigt. Obwohl ich klug ist, bin ich kein Fan dieses Ansatzes.
Anstatt eine Eins-zu-Eins-Zuordnung von Webkomponenten zu manuell geschaffenen React-Komponenten zu haben, bevorzuge ich nur eine React-Komponente, an die wir unseren Webkomponenten -Tag-Namen übergeben (Gegen-WC in unserem Fall)-zusammen mit allen Attributen und Eigenschaften-und für diese Komponente, um unsere Webkomponente zu rendern, dann den Schiedsrichter hinzuzufügen, dann herauszufinden, was ein Prop und was ist ein Prop und was ist ein Attribut. Das ist meiner Meinung nach die ideale L?sung. Ich kenne keine Bibliothek, die dies tut, aber es sollte unkompliziert sein zu erstellen. Lassen Sie uns es versuchen!
Dies ist die Verwendung , nach der wir suchen:
<wcwrapper wctag="counter-Wc" increment="{Increment}" color="{color}"></wcwrapper>
WCTAG ist der Webkomponenten -Tag -Name; Der Rest sind die Eigenschaften und Attribute, die wir weitergeben wollen.
So sieht meine Implementierung aus:
React, {CreateLement, Useref, uselayoutEffect, Memo} aus 'React'; const _wcwrapper = (props) => { const {WCTAG, Kinder, ... restprops} = props; const wcref = useref (null); useSelayouteffect (() => { const wc = wcref.current; für (const [Schlüssel, Wert] von Object.Entries (restProps)) { if (Schlüssel in WC) { if (wc [key]! == value) { WC [Schlüssel] = Wert; } } anders { if (wc.getAttribute (Schlüssel)! == value) { WC.SetAttribute (Schlüssel, Wert); } } } }); return createLement (WCTAG, {Ref: WCREF}); }; Export const wcwrapper = memo (_wcwrapper);
Die interessanteste Linie ist am Ende:
return createLement (WCTAG, {Ref: WCREF});
So erstellen wir ein Element, das mit einem dynamischen Namen reagiert. In der Tat ist dies das, was React normalerweise JSX verwandelt. Alle unsere Divs werden in CreateLement ("Div") -Anrufe konvertiert. Wir müssen diese API normalerweise nicht direkt nennen, aber es ist da, wenn wir sie brauchen.
Darüber hinaus m?chten wir einen Layout -Effekt ausführen und jede Requisite durchlaufen, die wir an unsere Komponente übergeben haben. Wir durchsuchen alle und prüfen, ob es sich um eine Eigenschaft mit einem in Schach handelt, das das Webkomponenten -Instanzobjekt sowie seine Prototyp -Kette überprüft, die alle Getter/Setzer fangen, die auf dem Klassenprototyp landen. Wenn kein solches Eigentum existiert, wird angenommen, dass es sich um ein Attribut handelt. In beiden F?llen haben wir es nur festgelegt, wenn sich der Wert tats?chlich ge?ndert hat.
Wenn Sie sich fragen, warum wir uselayouteffect anstelle von useEffect verwenden, m?chten wir diese Updates sofort ausführen, bevor unser Inhalt wiedergegeben wird. Beachten Sie auch, dass wir kein Abh?ngigkeitsarray für unsere UseLayouteffect haben. Dies bedeutet, dass wir dieses Update für jeden Render ausführen m?chten. Dies kann riskant sein, da React dazu neigt, viel wieder zu rendern. Ich habe dies verbessert, indem ich das Ganze in React.Memo einwickelte. Dies ist im Wesentlichen die moderne Version von React.pureComponent, was bedeutet, dass die Komponente nur dann erneut render wird, wenn sich eine der tats?chlichen Requisiten ge?ndert hat-und überprüft, ob dies über eine einfache Gleichstellungsprüfung geschieht.
Das einzige Risiko ist hier, dass Sie die Aktualisierungen nicht sehen, wenn Sie eine Objekt-Requisite übergeben, die Sie direkt ohne erneut zuordnen, ohne erneut zugewiesen zu werden. Dies ist jedoch sehr entmutigt, insbesondere in der React -Community, also würde ich mir keine Sorgen machen.
Bevor ich weitermachen würde, m?chte ich eine letzte Sache rufen. Sie sind vielleicht nicht zufrieden mit dem Aussehen der Verwendung. Auch diese Komponente wird so verwendet:
<wcwrapper wctag="counter-Wc" increment="{Increment}" color="{color}"></wcwrapper>
Insbesondere gef?llt Ihnen m?glicherweise nicht, dass Sie den Namen des Webkomponenten-Tags an die
<wcwrapper wctag="counter-Wc" increment="{Increment}" color="{color}"></wcwrapper>
… Dazu:
<counter wc ref="{wcref}" increment="{increment}" color="{color}"></counter>
Sie k?nnten wahrscheinlich sogar ein einzelnes Codemod schreiben, um dies überall zu tun, und dann
Die Implementierung
Ich wei?, es scheint, als h?tte es eine Reise gekostet haben, um hierher zu kommen. Wenn Sie sich erinnern, war unser ursprüngliches Ziel, den in meinem letzten Beitrag betrachteten Bildvorschehrcode zu übernehmen und in eine Webkomponente zu verschieben, damit er in jedem JavaScript -Framework verwendet werden kann. Reacts Fehlen an ordnungsgem??em Interop fügte der Mischung viele Details hinzu. Aber jetzt, da wir einen angemessenen Griff haben, wie eine Webkomponente erstellt und sie verwendet wird, wird die Implementierung fast antiklimaktisch sein.
Ich werde die gesamte Webkomponente hier fallen lassen und einige der interessanten Teile aufrufen. Wenn Sie es in Aktion sehen m?chten, finden Sie hier eine funktionierende Demo. Es wird zwischen meinen drei Lieblingsbüchern in meinen drei Lieblingsprogrammiersprachen wechseln. Die URL für jedes Buch ist jedes Mal einzigartig, sodass Sie die Vorschau sehen k?nnen. Sie m?chten jedoch wahrscheinlich die Dinge in Ihrem Devtools -Netzwerk -Registerkarte drosseln, um die Dinge wirklich zu sehen.
Ganze Code anzeigen
Klassenbuchcover erweitert Htmlelement { static beobachteteAttributes = ['url']; AttributEchangedCallback (Name, OldValue, NewValue) { if (name === 'url') { this.createmainimage (NewValue); } } Setzen Sie Vorschau (Val) { this.previewel = this.CreatePreview (Val); this.render (); } CreatePreview (Val) { if (typeof val === 'String') { return base64Preview (Val); } anders { return BlurhashPreview (Val); } } CreateMainimage (URL) { this.loaded = false; const img = document.createelement ('img'); img.alt = 'Buchcover'; img.addeventListener ('last', () = & gt; {{ if (img === this.imageel) { this.loaded = true; this.render (); } }); img.src = url; this.imageel = img; } connectedCallback () { this.render (); } render () { const elementmaybe = this.load? this.imageel: this.previewel; syncsinglechild (this, elementmaybe); } }
Zun?chst registrieren wir das Attribut, an dem wir interessiert sind, und reagieren, wenn es sich ?ndert:
static beobachteteAttributes = ['url']; AttributEchangedCallback (Name, OldValue, NewValue) { if (name === 'url') { this.createmainimage (NewValue); } }
Dies führt dazu, dass unsere Bildkomponente erstellt wird, was nur dann angezeigt wird, wenn sie geladen werden:
CreateMainimage (URL) { this.loaded = false; const img = document.createelement ('img'); img.alt = 'Buchcover'; img.addeventListener ('last', () => { if (img === this.imageel) { this.loaded = true; this.render (); } }); img.src = url; this.imageel = img; }
Als n?chstes haben wir unsere Vorschau -Eigenschaft, die entweder unsere Base64 -Vorschau -Zeichenfolge oder unser Blurhash -Paket sein kann:
Setzen Sie Vorschau (Val) { this.previewel = this.CreatePreview (Val); this.render (); } CreatePreview (Val) { if (typeof val === 'String') { return base64Preview (Val); } anders { return BlurhashPreview (Val); } }
Dies ist auf diejenigen Helferfunktion, die wir brauchen:
Funktion Base64Preview (Val) { const img = document.createelement ('img'); img.src = val; zurück img; } Funktion BlurhashPreview (Vorschau) { const canvasel = document.createelement ('canvas'); const {W: Breite, H: H?he} = Vorschau; canvasel.width = width; Canvasel.Height = H?he; const pixels = decode (Vorschau.BLURHASH, Breite, H?he); const ctx = canvasel.getContext ('2d'); Constant imagedata = ctx.createimagedata (Breite, H?he); Imagedata.Data.set (Pixel); ctx.putimagedata (Imagedata, 0, 0); Leinwand zurückgeben; }
Und schlie?lich unsere Render -Methode:
connectedCallback () { this.render (); } render () { const elementmaybe = this.load? this.imageel: this.previewel; syncsinglechild (this, elementmaybe); }
Und ein paar Helfermethoden, um alles zusammenzubinden:
Exportfunktion SyncSingLechild (Container, Kind) { const CurrentChild = Container.FirstelementChild; if (currentChild! == child) { ClearContainer (Container); if (Kind) { Container.AppendChild (Kind); } } } Exportfunktion ClearContainer (el) { Kind lassen; while ((child = el.firstelementChild)) { El.Removechild (Kind); } }
Es ist ein bisschen mehr Kesselplatte als wir brauchen würden, wenn wir dies in einem Framework erstellen, aber der Vorteil ist, dass wir dies in jedem Framework wiederverwenden k?nnen-obwohl React vorerst einen Wrapper ben?tigt, wie wir besprochen haben.
Krimskrams
Ich habe Lits React Wrapper bereits erw?hnt. Wenn Sie jedoch die Schablone verwenden, unterstützt sie tats?chlich eine separate Ausgangspipeline nur für React. Und die guten Leute von Microsoft haben auch etwas ?hnliches wie Lits Wrapper erstellt, das an die Fast -Web -Komponenten -Bibliothek angeschlossen ist.
Wie ich bereits erw?hnt habe, werden alle Frameworks, die nicht mit React benannt sind, die Einstellungs -Webkomponenteneigenschaften für Sie verarbeiten. Beachten Sie nur, dass einige einige besondere Aromen von Syntax haben. Beispielsweise nimmt beispielsweise mit Solid.js
Einpacken
Webkomponenten sind ein interessanter, oft nicht genutzter Bestandteil der Webentwicklungslandschaft. Sie k?nnen dazu beitragen, Ihre Abh?ngigkeit von einem einzelnen JavaScript -Framework durch Verwaltung Ihrer Benutzeroberfl?che oder ?Blatt“ -Komponenten zu verringern. W?hrend das Erstellen dieser als Webkomponenten - im Gegensatz zu Svelte- oder React -Komponenten - nicht so ergonomisch ist, ist der Vorteil, dass sie weithin wiederverwendbar sind.
Das obige ist der detaillierte Inhalt vonAufbau interoperabler Webkomponenten, die funktionieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Es gibt drei M?glichkeiten, einen CSS -Laderotator zu erstellen: 1. Verwenden Sie den Basisrotator der Grenzen, um eine einfache Animation durch HTML und CSS zu erreichen. 2. Verwenden Sie einen benutzerdefinierten Rotator mit mehreren Punkten, um den Sprungeffekt durch verschiedene Verz?gerungszeiten zu erreichen. 3. Fügen Sie einen Rotator in die Taste hinzu und wechseln Sie den Klassen über JavaScript, um den Ladestatus anzuzeigen. Jeder Ansatz betont die Bedeutung von Entwurfsdetails wie Farbe, Gr??e, Zug?nglichkeit und Leistungsoptimierung, um die Benutzererfahrung zu verbessern.

Um mit CSS -Browser -Kompatibilit?t und Pr?fixproblemen umzugehen, müssen Sie die Unterschiede im Browser -Support verstehen und Anbieterpr?fixe vernünftigerweise verwenden. 1. Verstehen Sie gemeinsame Probleme wie Flexbox und Grid -Unterstützung, Position: Sticky Invaly und Animationsleistung ist unterschiedlich. 2. überprüfen Sie den Best?tigungsunterstützungsstatus von Caniuse. 3. Verwenden Sie korrekt -webkit-, -moz-, -ms-, -o- und andere Herstellerpr?fixe; 4. Es wird empfohlen, Autoprefixer zu verwenden, um automatisch Pr?fixe hinzuzufügen. 5. Postcss installieren und Browserlist konfigurieren, um den Zielbrowser anzugeben. 6. automatisch die Kompatibilit?t w?hrend des Baus bew?ltigen; 7. Modernizr -Erkennungsmerkmale k?nnen für alte Projekte verwendet werden; 8. Keine Notwendigkeit, die Konsistenz aller Browser zu verfolgen,

ThemaNDiffercesbetweenplay: Inline, Block, Andinline-Blockinhtml/CsSarelayoutBehavior, Spaceusage und Stylingcontrol.1.inlineelementsflowwithtext, Don'tstartonNewlines, Ignorewidth/HeighthThorchingstyhorching-/idelthorchorching/ardaldhordhortaliTalding/ardaldhordelthortex

Durch das Festlegen des von Ihnen besuchten Links k?nnen Sie die Benutzererfahrung verbessern, insbesondere in inhaltsintensiven Websites, um den Benutzern dabei zu helfen, sich besser zu navigieren. 1. Verwenden Sie CSS: Besuchte Pseudoklasse, um den Stil des besuchten Links wie Farb?nderungen zu definieren. 2. Beachten Sie, dass der Browser nur eine ?nderung einiger Attribute aufgrund von Datenschutzbeschr?nkungen erm?glicht. 3. Die Farbauswahl sollte mit dem Gesamtstil koordiniert werden, um abrupte abrupt zu werden. 4. Das mobile Terminal zeigt diesen Effekt m?glicherweise nicht an. Es wird empfohlen, ihn mit anderen visuellen Eingabeaufforderungen wie Icon -Auxiliary -Logos zu kombinieren.

Verwenden Sie das Clip-Pfad-Attribut von CSS, um Elemente in benutzerdefinierte Formen wie Dreiecke, kreisf?rmige Kerben, Polygone usw. zu erregen, ohne sich auf Bilder oder SVGs zu verlassen. Zu den Vorteilen geh?ren: 1.. Unterstützt eine Vielzahl von Grundformen wie Circle, Ellipse, Polygon usw.; 2. reagierende Anpassung und anpassbar an mobile Terminals; 3. Einfach zu animation und kann mit Hover oder JavaScript kombiniert werden, um dynamische Effekte zu erzielen. 4. Es wirkt sich nicht auf den Layoutfluss aus und erfüllt nur den Anzeigebereich. H?ufige Verwendungen sind z. B. kreisf?rmiger Clip-Pfad: Kreis (50pxatcenter) und Dreieck-Clip-Pfad: Polygon (50%0%, 100 0%, 0 0%). Beachten

Um reaktionsschnelle Bilder mit CSS zu erstellen, kann es haupts?chlich durch die folgenden Methoden erreicht werden: 1. Verwenden Sie maximale Breite: 100% und H?he: Auto, damit das Bild an die Containerbreite anpasst und gleichzeitig den Anteil beibeh?lt. 2. Verwenden Sie die SRCSet- und Gr??enattribute von HTML, um die an verschiedenen Bildschirme angepassten Bildquellen intelligent zu laden. 3.. Verwenden Sie Objektfit und Objektposition, um die Bildaufbindung und Fokusanzeige zu steuern. Gemeinsam stellen diese Methoden sicher, dass die Bilder auf verschiedenen Ger?ten klar und wundersch?n pr?sentiert werden.

Die Auswahl der CSS -Einheiten h?ngt von den Entwurfsanforderungen und den reaktionsschnellen Anforderungen ab. 1.PX wird für die feste Gr??e verwendet, geeignet für eine pr?zise Kontrolle, aber mangelnde Elastizit?t; 2.Em ist eine relative Einheit, die leicht durch den Einfluss des übergeordneten Elements verursacht wird, w?hrend REM basierend auf dem Wurzelelement stabiler ist und für die globale Skalierung geeignet ist. 3.VW/VH basiert auf der Ansichtsfenstergr??e, die für das reaktionsschnelle Design geeignet ist. Die Leistung unter extremen Bildschirmen sollte jedoch Aufmerksamkeit geschenkt werden. 4. Bei der Auswahl sollte es ermittelt werden, ob reaktionsschnelle Anpassungen, Elementhierarchiebeziehungen und Ansichtsfensterabh?ngigkeit festgelegt werden. Angemessener Gebrauch kann die Layoutflexibilit?t und -wartung verbessern.

Verschiedene Browser weisen Unterschiede in der CSS -Analyse auf, was zu inkonsistenten Anzeigeeffekten führt, haupts?chlich die Differenzentscheidung, die Berechnung des Boxmodells, die Flexbox- und Raster -Layout -Unterstützung und das inkonsistente Verhalten bestimmter CSS -Attribute. 1. Die Standardstilverarbeitung ist inkonsistent. Die L?sung besteht darin, CSSReset oder Normalize.css zu verwenden, um den anf?nglichen Stil zu vereinen. 2. Die Box -Modellberechnung der alten Version von IE ist unterschiedlich. Es wird empfohlen, eine einheitliche Boxgr??e: Border-Box zu verwenden. 3. Flexbox und Grid führen in Kantenf?llen oder in alten Versionen unterschiedlich ab. Weitere Tests und verwenden Sie Autoprefixer; 4. Einige CSS -Attributverhalten sind inkonsistent. Caniuse muss konsultiert und herabgestuft werden.
