Beispiel für die Verwendung von JSX zur Entwicklung einer Markup-Komponente (Front-End-Komponentenbildung)

Beispiel für die Verwendung von JSX zur Entwicklung einer Markup-Komponente (Front-End-Komponentenbildung)

Hier bauen wir ein Komponentensystem von Grund auf. Zunächst wissen wir aus den vorherigen Artikeln „Grundlagen der Front-End-Komponentenbildung“ und „Verwenden von JSX zum Einrichten eines Komponentenparsers“, dass eine Komponente eine Umgebung ist, auf die über Markup und JavaScript zugegriffen werden kann.

Unser erster Schritt besteht also darin, eine Umgebung zu schaffen, in der wir Markup verwenden können. Hier lernen wir, wie wir JSX zum Stylen unseres Markups verwenden. Hier verwenden wir JSX, dasselbe wie React, um unsere Komponenten zu stylen.


Aufbau einer JSX-Umgebung

Im Allgemeinen wird JSX als Teil von React betrachtet. Tatsächlich definiert Facebook JSX als reine Spracherweiterung. Und dieses JSX kann auch von anderen Komponentensystemen verwendet werden.

Wir können es sogar verwenden, um schnell HTML-Tags zu erstellen.

Einrichten des Projekts

Beginnen wir also mit den Grundlagen. Zuerst müssen wir ein neues Projektverzeichnis erstellen:

mkdir jsx-Komponente

NPM initialisieren

Erstellen Sie diesen Projektordner natürlich in dem Verzeichnis Ihrer Wahl. Nachdem wir den Ordner erstellt haben, können wir das Verzeichnis aufrufen und npm initialisieren.

npm init

Nach der Ausführung des obigen Befehls werden einige Projektkonfigurationsoptionen angezeigt. Sie können diese bei Bedarf ausfüllen. Wir können jedoch auch einfach die Eingabetaste drücken und dann können die Studierenden, die es benötigen, package.json öffnen und es später selbst ändern.

Webpack installieren

Viele Studenten sollten von Wepack gehört haben, mit dem wir eine gewöhnliche JavaScript-Datei in eine Datei umwandeln können, in der verschiedene Import- und Anforderungsdateien zusammen verpackt werden können.

Also müssen wir webpack installieren. Natürlich können wir auch npx verwenden, um webpack direkt zu verwenden, oder wir können webpack-cli global installieren.

Daher verwenden wir hier die globale Installation von webpack-cli:

npm install -g webpack webpack-cli

Nachdem die Installation abgeschlossen ist, können wir die installierte Webpack-Version überprüfen, indem wir den folgenden Befehl eingeben. Wenn nach der Ausführung kein Fehler auftritt und eine Versionsnummer angezeigt wird, beweist dies, dass wir es erfolgreich installiert haben.

webpack --version

Installieren Sie Babel

Da JSX ein Babel-Plugin ist, müssen wir nacheinander Webpack, Babel-Loader, Babel und das Babel-Plugin installieren.

Eine weitere Verwendung von Babel besteht darin, dass es eine neue Version von JavaScript in eine alte Version von JavaScript kompilieren kann, sodass wir die Ausführung in mehreren älteren Browserversionen unterstützen können.

Um Babel zu installieren, müssen wir nur den folgenden Befehl ausführen.

npm install --save-dev webpack babel-loader

Was wir hier beachten müssen, ist, dass wir --save-dev hinzufügen müssen, damit wir Babel zu unseren Entwicklungsabhängigkeiten hinzufügen.

Nach der Ausführung sollten wir die im Bild oben angezeigte Meldung sehen.

Um zu überprüfen, ob wir es richtig installiert haben, können wir package.json in unserem Projektverzeichnis öffnen.

{
 "Name": "jsx-Komponente",
 "version": "1.0.0",
 "Beschreibung": "",
 "main": "index.js",
 "Skripte": {
 "test": "echo \"Fehler: kein Test angegeben\" && exit 1"
 },
 "Autor": "",
 "Lizenz": "ISC",
 "devAbhängigkeiten": {
 "babel-loader": "^8.1.0",
 "webpack": "^5.4.0"
 }
}

OK, wir können sehen, dass sich unter devDependencies tatsächlich die beiden Pakete befinden, die wir gerade installiert haben. Wenn Sie immer noch besorgt sind, können Sie package.json noch einmal überprüfen.

Konfigurieren von Webpack

An diesem Punkt müssen wir die Webpack-Konfiguration konfigurieren. Webpack konfigurieren Wir müssen eine Konfigurationsdatei webpack.config.js erstellen.

Erstellen Sie eine Datei webpack.config.js im Stammverzeichnis unseres Projekts.

Zunächst einmal ist die Webpack-Konfiguration ein Node.JS-Modul, daher müssen wir module.exports verwenden, um seine Einstellungen zu schreiben. Dies ist eine gängige Konfigurationsmethode für frühe Node.JS-Tools. Zur Konfiguration wird eine JavaScript-Datei verwendet, sodass der Konfiguration eine gewisse Logik hinzugefügt werden kann.

modul.exports = {}

Das Grundlegendste an Webpack ist, dass Sie einen Eintrag einrichten (seine Eintragsdatei festlegen) müssen. Hier haben wir einfach ein main.js eingerichtet.

modul.exporte = {
 Eintrag: "./main.js"
}

Zu diesem Zeitpunkt können wir zunächst unsere main.js Datei in unserem Stammverzeichnis erstellen. Fügen wir zunächst eine einfache for Schleife hinzu.

// Inhalt der Datei main.js für (let i of [1, 2, 3]) {
 konsole.log(i);
}

Auf diese Weise ist die Grundkonfiguration unseres Webpacks konfiguriert. Lassen Sie uns Webpack im Stammverzeichnis ausführen, um unsere Datei main.js zu packen und zu sehen. Wir müssen nur den folgenden Befehl ausführen:

Webpack 

Nachdem die Ausführung abgeschlossen ist, wird in der Befehlszeilenschnittstelle eine Eingabeaufforderung wie oben angezeigt.

Schüler, die auf Details achten, werden auf jeden Fall die Hand heben und fragen, Klassenkameraden! Es liegt ein Fehler in Ihrer Befehlszeile vor! Der gelbe Teil gibt uns zwar eine Warnung, aber das spielt keine Rolle, unsere nächste Konfiguration wird das Problem beheben.

Zu diesem Zeitpunkt werden wir feststellen, dass in unserem Stammverzeichnis ein neuer Ordner dist generiert wird. Dies ist der von Webpack standardmäßig generierte Ordner. Alle unsere gepackten JavaScripts und Ressourcen werden standardmäßig in diesem Ordner abgelegt.

Hier finden wir eine gepackte main.js Datei im Ordner dist . Dies ist main.js , die wir geschrieben haben und die von webpack gepackt wurde.

Dann öffnen wir es und sehen den JavaScript-Code, nachdem er von Babel kompiliert wurde. Wir werden feststellen, dass unseren wenigen Codezeilen eine Menge Dinge hinzugefügt wurden, aber darüber müssen wir uns keine Gedanken machen, das ist die „Meow-Power“ von Webpack.

Am Ende des Codes können Sie immer noch for Schleife sehen, die wir geschrieben haben. Sie wurde nur ein wenig geändert, aber ihre Funktion ist dieselbe.

Installieren Sie Babel-Loader

Als nächstes installieren wir babel-loader. Tatsächlich ist babel-loader nicht direkt von babel abhängig, daher müssen wir @babel/core und @babel/preset-env separat installieren. Um es zu installieren, müssen wir nur die folgende Befehlszeile ausführen:

npm install --save-dev @babel/core @babel/preset-env 

Das Endergebnis ist wie oben dargestellt und beweist, dass die Installation erfolgreich war. Jetzt müssen wir es in webpack.config.js konfigurieren, damit wir beim Verpacken den Babel-Loader verwenden können.

Fügen Sie nach entry von webpack.config.js , den wir oben konfiguriert haben, eine Option namens module hinzu.

Dann können wir dem Modul auch eine rules hinzufügen, die wir beim Erstellen verwenden. rules ist eine Konfiguration vom Array-Typ und jede Regel besteht hier aus einem test und einer use .

  • prüfen:

Der Wert von test ist ein regulärer Ausdruck, der zum Abgleichen der Dateien verwendet wird, für die wir diese Regel verwenden müssen. Hier müssen wir alle JavaScript-Dateien abgleichen, daher können wir /\.js/ verwenden.

  • verwenden:

loader: Fügen Sie einfach den Namen unseres babel-loader hinzu

  • Optionen:

Voreinstellungen:

  • Hier sind die Loader-Optionen, hier müssen wir @babel/preset-env hinzufügen

Schließlich sieht unsere Konfigurationsdatei folgendermaßen aus:

modul.exporte = {
 Eintrag: './main.js',
 Modul: {
 Regeln:
 {
 Test: /\.js$/,
 verwenden: {
 Lader: 'babel-loader',
 Optionen:
 Voreinstellungen: ['@babel/preset-env'],
 },
 },
 },
 ],
 },
};

Nachdem wir dies konfiguriert haben, können wir Babel ausführen, um es auszuprobieren. Wie zuvor müssen wir nur webpack auf der Befehlszeile ausführen.

Wenn unsere Konfigurationsdatei richtig geschrieben ist, sollten wir die in der Abbildung oben gezeigten Ergebnisse sehen.

Dann gehen wir in dist , öffnen unser kompiliertes main.js und schauen uns das Kompilierungsergebnis an, nachdem wir dieses Mal babel-loader verwendet haben.

Nach der Kompilierung werden wir feststellen, dass for of -Schleife in eine normale for Schleife kompiliert wurde. Dies beweist auch, dass unser Babel-Loader effektiv ist und unsere neue Version der JavaScript-Syntax korrekt in eine JavaScript-Syntax programmiert, die mit älteren Browsern kompatibel ist.

An diesem Punkt haben wir die für unser JSX erforderliche Umgebung installiert und erstellt.

Moduskonfiguration

Schließlich müssen wir auch eine Umgebungskonfiguration in webpack.config.js hinzufügen. Dies kann jedoch als optional bezeichnet werden, wir tun es jedoch zur Vereinfachung der täglichen Entwicklung.

Daher müssen wir einen mode in webpack.config.js hinzufügen und verwenden development als Wert dieser Eigenschaft. Diese Konfiguration zeigt an, dass wir uns im Entwicklermodus befinden.

Im Allgemeinen fügt die Webpack-Konfiguration, die wir in das Code-Repository schreiben, standardmäßig diesen mode: 'development' -Konfiguration. Wenn wir es tatsächlich veröffentlichen, ändern wir es in mode: 'production' .

modul.exporte = {
 Eintrag: './main.js',
 Modus: "Entwicklung",
 Modul: {
 Regeln:
 {
 Test: /\.js$/,
 verwenden: {
 Lader: 'babel-loader',
 Optionen:
 Voreinstellungen: ['@babel/preset-env'],
 },
 },
 },
 ],
 },
};

Nach der Änderung verwenden wir webpack zum Kompilieren und sehen, was der Unterschied in unserem main.js ist.

Offensichtlich haben wir festgestellt, dass der kompilierte Code nicht in einer Zeile komprimiert ist. Auf diese Weise können wir den von webpack generierten Code debuggen. Hier können wir feststellen, dass unser Code in main.js in einen String umgewandelt und in eine eval() Funktion eingefügt wird. Unser Code wird in eval eingefügt, sodass wir ihn beim Debuggen als separate Datei verwenden können.

JSX importieren

Alles ist bereit, bis auf den Ostwind. Und zum Schluss: Wie führen wir JSX ein? Sehen wir uns vor dem Importieren an, was passiert, wenn wir die JSX-Syntax in unserem main.js mit der aktuellen Konfiguration verwenden. Als Programmierer müssen wir immer ein bisschen abenteuerlustig sein!

Also fügen wir diesen Code zu unserem main.js hinzu:

var a = <div/>

Lassen Sie uns dann Webpack ausführen und sehen!

Gute Arbeit! Tatsächlich wurde ein Fehler gemeldet. Der Fehler hier sagt uns, dass das „Kleiner-als-Zeichen“ nach = nicht verwendet werden kann, aber in der normalen JSX-Syntax sind dies tatsächlich die „spitzen Klammern“ des HTML-Tags. Da es keinen Kompilierungsprozess für die JSX-Syntax gibt, geht JavaScript standardmäßig davon aus, dass dies das „Kleiner-als-Zeichen“ ist.

Was müssen wir also tun, damit unser Webpack-Kompilierungsprozess die JSX-Syntax unterstützt? Hier müssen wir tatsächlich ein äußerst wichtiges Paket hinzufügen, und der Name dieses Pakets ist sehr lang und lautet @babel/plugin-transform-react-jsx . Führen wir nun einen Befehl aus, um dieses Paket zu installieren:

npm install --save-dev @babel/plugin-transform-react-jsx

Nach der Installation müssen wir es auch zur Webpack-Konfiguration hinzufügen. Wir müssen ['@babel/plugin-transform-react-jsx'] zur plugins -Konfiguration bei use in rules im module hinzufügen.

Dann sieht unsere Webpack-Konfigurationsdatei schließlich so aus:

modul.exporte = {
 Eintrag: './main.js',
 Modus: "Entwicklung",
 Modul: {
 Regeln:
 {
 Test: /\.js$/,
 verwenden: {
 Lader: 'babel-loader',
 Optionen:
 Voreinstellungen: ['@babel/preset-env'],
 Plugins: ['@babel/plugin-transform-react-jsx'],
 },
 },
 },
 ],
 },
};

Lassen Sie uns nach der Konfiguration Webpack ausführen. Zu diesem Zeitpunkt stellten wir fest, dass kein Fehler mehr vorlag. Dies beweist, dass unser Code jetzt das Schreiben mit JSX-Syntax unterstützt.

Schauen wir uns abschließend die endgültige Wirkung der Programmierung an.

Wir werden feststellen, dass <div/> das wir in eval hinzugefügt haben, in einen Funktionsaufruf von React.createElement("div", null) übersetzt wird.

Sehen wir uns also an, wie wir React.createElement implementieren sollten und ob wir es durch unseren eigenen Funktionsnamen ersetzen können.

Grundlegende JSX-Verwendung

Versuchen wir zunächst, JSX zu verstehen. JSX ist eigentlich nur eine Abkürzung in der Codesyntax. Am Ende des vorherigen Abschnitts haben wir gesehen, dass nach der Kompilierung der JSX-Syntax ein Aufruf von React.createElement erscheint.

JSX-Grundlagen

Daher ändern wir hier zuerst das JSX-Plugin im Webpack und geben ihm einen benutzerdefinierten Funktionsnamen zur Elementerstellung. Wir öffnen webpack.config.js und ändern es im Bereich Plugins.

modul.exporte = {
 Eintrag: './main.js',
 Modus: "Entwicklung",
 Modul: {
 Regeln:
 {
 Test: /\.js$/,
 verwenden: {
 Lader: 'babel-loader',
 Optionen:
 Voreinstellungen: ['@babel/preset-env'],
 Plugins: [
				[
					'@babel/plugin-transform-react-jsx',
					{ pragma: 'Element erstellen' }
				]
			],
 },
 },
 },
 ],
 },
};

Oben haben wir einfach den ursprünglichen Parameter ['@babel/plugin-transform-react-jsx'] [['@babel/plugin-transform-react-jsx', {pragma: 'createElement'}]] geändert. Durch Hinzufügen dieses pragma -Parameters können wir den Funktionsnamen des von uns erstellten Elements anpassen.

Mit dieser Änderung hat unser JSX nichts mehr mit dem React-Framework zu tun. Lassen Sie uns webpack ausführen und uns den endgültigen generierten Effekt ansehen. Wir werden feststellen, dass aus React.createElement createElement wird.

Als nächstes fügen wir eine HTML-Datei hinzu, um unser main.js auszuführen und auszuprobieren. Erstellen Sie zunächst eine main.html im Stammverzeichnis und geben Sie den folgenden Code ein:

<script src="./main.js"></script>

Anschließend führen wir diese HTML-Datei aus und öffnen sie im Browser.

Zu diesem Zeitpunkt gibt unsere Konsole einen Fehler aus und unser createElement ist nicht definiert. Tatsächlich haben wir diese Funktion nicht in main.js definiert und kann deshalb nicht gefunden werden.

Daher müssen wir selbst eine createElement -Funktion schreiben. Wir öffnen main.js direkt im Stammverzeichnis, löschen die vorherige for Schleife und fügen dann den folgenden Code hinzu:

Funktion erstelleElement() {
 zurückkehren;
}

sei a = <div />;

Hier geben wir einfach leer zurück und machen diese Funktion zuerst aufrufbar. Wir kompilieren einmal mit Webpack neu und aktualisieren dann unsere main.html-Seite. Zu diesem Zeitpunkt stellen wir fest, dass kein Fehler vorliegt und der Vorgang normal ausgeführt werden kann.

Implementieren der Funktion „createElement“

In unserem kompilierten Code können wir sehen, dass das JSX-Element beim Aufruf von createElement zwei Parameter übergibt. Das erste Argument ist div , das zweite ist null .

Warum ist der zweite Parameter hier null ? Tatsächlich wird der zweite Parameter verwendet, um die Attributliste zu übergeben. Wenn wir dem Div in main.js eine id="a" hinzufügen, sehen wir, welche Änderungen bei der endgültigen Kompilierung auftreten.

Wir werden feststellen, dass der zweite Parameter ein im Schlüssel-Wert-Modus gespeichertes JavaScript-Objekt wird. Wenn wir jetzt darüber nachdenken, ist JSX nicht so mysteriös. Es kompiliert einfach das HTML, das wir normalerweise schreiben, in ein JavaScript-Objekt. Wir können es uns als eine Art „syntaktischen Zucker“ vorstellen.

Da JSX jedoch die Struktur des Codes beeinflusst, wird es im Allgemeinen nicht als syntaktischer Zucker bezeichnet.

Als nächstes schreiben wir etwas komplexeres JSX. Wir werden unserem ursprünglichen Div einige untergeordnete Elemente hinzufügen.

Funktion erstelleElement() {
 zurückkehren;
}

sei a = (
 <div id="ein">
 <span></span>
 <span></span>
 <span></span>
 </div>
);

Lassen Sie uns abschließend die Webpack-Verpackung ausführen, um die Wirkung zu sehen.

In der Konsole können wir sehen, dass das endgültige kompilierte Ergebnis ein rekursiver Aufruf der Funktion createElement ist. Tatsächlich hat sich hier eine Baumstruktur gebildet.

Das übergeordnete Element ist das Div-Element der ersten Ebene und das untergeordnete Element ist der Parameter, der an die erste Funktion „createElement“ übergeben wird. Da unsere Spans keine Attribute haben, ist der zweite Parameter aller nachfolgenden createElements null .

Basierend auf dem hier angezeigten Kompilierungsergebnis können wir analysieren, wie die Parameter unserer Funktion createElement lauten sollten.

  • Der erste Parametertyp type ist der Typ dieses Tags
  • Das zweite attribute - alle Attribute und Werte im Tag
  • Die restlichen Parameter sind alle untergeordnete Eigenschaften ...children - Hier verwenden wir eine relativ neue Syntax in JavaScript ...children bedeutet, dass alle folgenden Parameter (unbestimmte Anzahl) in ein Array umgewandelt und der Variable children zugewiesen werden.

Dann kann unsere createElement -Funktion wie folgt geschrieben werden:

Funktion createElement(Typ, Attribute, ...Kinder) {
 zurückkehren;
}

Wir haben die Funktion, aber was kann diese Funktion? Tatsächlich kann diese Funktion für alles verwendet werden. Da sie wie eine DOM-API aussieht, können wir sie in ein Entity-DOM umwandeln, das nichts mit React zu tun hat.

Beispielsweise können wir in dieser Funktion das element dieses type zurückgeben. Hier fügen wir diesem Element alle übergebenen attributes hinzu und können diesem Element untergeordnete Elemente anhängen.

Zum Erstellen eines Elements können wir createElement(type) verwenden, zum Hinzufügen von Attributen können wir setAttribute() verwenden und zum Anhängen von untergeordneten Elementen können wir appendChild() verwenden.

Funktion createElement(Typ, Attribute, ...Kinder) {
 // Ein Element erstellen let element = document.createElement(type);
 //Attribute für (let-Attribut in Attributen) { anhängen
 element.setAttribute(attribute);
 }
 //Alle untergeordneten Elemente anhängen für (let child of children) {
 element.appendChild(Kind);
 }
 //Schließlich ist unser Element ein Knoten// also können wir direkt das Return-Element zurückgeben;
}

Hier implementieren wir die Logik der Funktion createElement . Schließlich müssen wir auch unseren DOM-Knoten auf der Seite mounten. So können wir es direkt am Körper montieren.

// Fügen Sie diesen Code am Ende von main.js hinzu let a = (
 <div id="ein">
 <span></span>
 <span></span>
 <span></span>
 </div>
);

Dokument.Body.AnhängenKind(a);

Auch hier gilt es zu beachten, dass in unserer main.html kein Body-Tag vorhanden ist. Sonst können wir diesen nicht am Body einhängen. Also müssen wir hier das Body-Tag zu main.html hinzufügen.

<Körper></Körper>
<script src="dist/main.js"></script>

OK, jetzt können wir es mit Webpack verpacken und die Wirkung sehen.

Wunderbar! Wir haben den Knoten erfolgreich generiert und an den Körper angehängt. Wenn wir jedoch einen Textabschnitt zu unserem div hinzufügen, wird ein Textknoten an unsere Funktion createElement übergeben. Es ist unnötig zu erwähnen, dass unsere Funktion createElement mit ihrer aktuellen Logik keine Textknoten verarbeiten kann.

Als nächstes fügen wir die Logik zur Verarbeitung von Textknoten hinzu, aber vorher löschen wir das Span-Tag im Div und ersetzen es durch den Text „Hallo Welt“.

let a = <div id="a">Hallo Welt</div>;

Bevor wir die Logik des Textknotens hinzufügen, verpacken wir ihn zunächst mit Webpack. Bevor wir den untergeordneten Knoten aufhängen, sehen wir uns an, welche spezifischen Fehler gemeldet werden.

Zunächst können wir sehen, dass dort, wo createElement aufgerufen wird, unser Text als Zeichenfolge übergeben wird. Anschließend erhält dieser Parameter den untergeordneten Knoten. In unserer Logik verwenden wir appendChild , das den DOM-Knoten erhält. Unsere Textzeichenfolge ist offensichtlich kein Knoten, daher wird ein Fehler gemeldet.

Durch diese Debugging-Methode können wir sofort lokalisieren, wo wir Logik hinzufügen müssen, um unsere Funktion zu implementieren. Diese Methode kann auch als Abkürzung betrachtet werden.

Kehren wir also zu main.js zurück. Bevor wir den untergeordneten Knoten anfügen, bestimmen wir den Typ des untergeordneten Knotens. Wenn sein Typ eine Zeichenfolge vom Typ „String“ ist, erstellen wir mit createTextNode() einen Textknoten und fügen ihn dann an das übergeordnete Element an. Auf diese Weise haben wir die Verarbeitung der Zeichenknoten abgeschlossen.

Funktion createElement(Typ, Attribute, ...Kinder) {
 // Ein Element erstellen let element = document.createElement(type);
 //Attribute für (Name in Attributen lassen) aufhängen {
 element.setAttribute(name, Attribute[name]);
 }
 //Alle untergeordneten Elemente anhängen für (let child of children) {
 wenn (Typ des untergeordneten Elements === 'Zeichenfolge') 
		Kind = Dokument.createTextNode(Kind);
 element.appendChild(Kind);
 }
 //Schließlich ist unser Element ein Knoten// also können wir direkt das Return-Element zurückgeben;
}

let a = <div id="a">Hallo Welt</div>;

Dokument.Body.AnhängenKind(a);

Nachdem wir diesen neuesten Webpack-Code zum Verpacken verwendet haben, können wir sehen, dass unser Text im Browser angezeigt wird.

An diesem Punkt ist createElement bereits eine nützliche Sache und wir können es verwenden, um einige DOM-Operationen durchzuführen. Es kann sogar den sich wiederholenden und langwierigen Vorgang des eigenen Schreibens von document.createElement vollständig ersetzen.

Hier können wir überprüfen, ob wir unsere vorherigen drei Bereiche wieder zum Div hinzufügen und jedem Bereich Text hinzufügen. 11

sei a = (
 <div id="ein">
 hallo Welt:
 <span>ein</span>
 <span>b</span>
 <span>c</span>
 </div>
);

Nachdem wir das Webpack erneut gepackt haben, können wir sehen, dass dieser DOM-Vorgang tatsächlich abgeschlossen werden kann.

Der aktuelle Code kann bereits bestimmte grundlegende Komponentenfunktionen erreichen.

Implementieren von benutzerdefinierten Tags

Früher haben wir einige Tags verwendet, die mit HTML geliefert wurden. Was passiert, wenn wir jetzt das d in div in ein großes D ändern?

sei a = (
 <Div id="a">
 hallo Welt:
 <span>ein</span>
 <span>b</span>
 <span>c</span>
 </Div>
); 

Wie erwartet wird ein Fehler gemeldet. Aber genau hier liegt der Schlüssel, um die Grundursache des Problems zu finden. Hier stellen wir fest, dass, wenn wir div in Div ändern, sich das an unser createElement übergebene div von der Zeichenfolge „div“ in eine Div Klasse ändert.

Natürlich ist die Div-Klasse in unserem JavaScript nicht definiert, daher wird ein Fehler gemeldet, der darauf hinweist, dass Div nicht definiert ist. Wenn wir wissen, wo das Problem liegt, können wir es lösen. Zuerst müssen wir das undefinierte Problem lösen, also erstellen wir zuerst eine Div-Klasse.

//Füge die Klasse Div {} nach der Funktion createElment hinzu

Dann müssen wir in createElement eine Typbeurteilung vornehmen. Wenn der Typ, auf den wir stoßen, ein Zeichentyp ist, behandeln wir ihn auf die ursprüngliche Weise. Wenn wir auf eine andere Situation stoßen, instanziieren wir den übergebenen type .

Funktion createElement(Typ, Attribute, ...Kinder) {
 //Element erstellen let element;
 wenn (Typ von Typ === 'Zeichenfolge') {
 Element = Dokument.Elementerstellen(Typ);
 } anders {
 Element = neuer Typ();
 }

 //Attribute für (Name in Attributen lassen) aufhängen {
 element.setAttribute(name, Attribute[name]);
 }
 //Alle untergeordneten Elemente anhängen für (let child of children) {
 wenn (Typ des untergeordneten Elements === 'Zeichenfolge') untergeordnetes Element = Dokument.createTextNode(untergeordnetes Element);
 element.appendChild(Kind);
 }
 //Schließlich ist unser Element ein Knoten// also können wir direkt das Return-Element zurückgeben;
}

Hier haben wir eine weitere Frage: Gibt es eine Möglichkeit, benutzerdefinierte Tags wie unsere normalen HTML-Tags funktionieren zu lassen? In der neuesten Version des DOM-Standards gibt es hierfür eine Möglichkeit. Wir müssen lediglich den Namen und den Typ unseres benutzerdefinierten Tags registrieren.

In unserer aktuellen, sichereren Browserversion wird dies jedoch nicht empfohlen. Daher wird bei Verwendung unseres benutzerdefinierten Elements empfohlen, dass wir selbst eine Schnittstelle schreiben.

Zuerst müssen wir eine Tag-Klasse erstellen, die es ermöglicht, jedes Tag in unserem DOM-Baum einzubinden, wie die Elemente unserer vorherigen gewöhnlichen HTML-Tags.

Es wird die folgenden Methoden enthalten:

  • mountTo() —— Erstellen Sie einen Elementknoten für die spätere Einbindung in parent Knoten
  • setAttribute() - alle Attribute an ein Element anhängen
  • appendChild() - hängt alle Kindelemente an ein Element an

Lassen Sie uns zunächst einfach die Methode mountTo in unserer Div Klasse implementieren. Hier müssen wir auch die Methoden setAttribute und appendChild hinzufügen, da es in unserem createElement eine Logik zum Mounten von Attribut-Unterelementen gibt. Wenn diese beiden Methoden nicht verfügbar sind, wird ein Fehler gemeldet. Aber dieses Mal implementieren wir die Logik dieser beiden Methoden nicht und lassen den Methodeninhalt einfach leer.

Klasse Div {
 setAttribute() {}
 anhängenKind() {}
 mountTo(übergeordnet) {
 dies.root = Dokument.createElement('div');
 übergeordnetes Element.anhängenKind(diese.Wurzel);
 }
}

Dies ist eigentlich ganz einfach. Erstellen Sie zunächst einen Div-Elementknoten für root in der Klasse und hängen Sie diesen Knoten dann an das übergeordnete Element dieses Elements an. Dieses parent wird als Parameter übergeben.

Dann können wir unseren ursprünglichen body.appendChild-Code ändern, um die mountTo Methode zum Mounten unserer benutzerdefinierten Elementklasse zu verwenden.

// Dokument.Body.AppendChild(a);
a.mountTo(Dokument.Textkörper);

Mit dem aktuellen Code verpacken wir ihn mit webpack, um die Wirkung zu sehen:

Wir können sehen, dass unser benutzerdefiniertes Div-Element korrekt am Körper montiert ist. Aber die Span-Tags im Div sind nicht gemountet. Wenn es wie ein normales Div funktionieren soll, müssen wir unsere setAttribute und appendChild -Logik implementieren.

Versuchen wir als Nächstes, die verbleibende Implementierungslogik zu vervollständigen. Bevor wir mit dem Schreiben von setAttribute und appendChild beginnen, müssen wir unserer Div-Klasse einen constructor hinzufügen. Hier können wir das Element erstellen und es per Proxy an root senden.

Konstruktor() {
 dies.root = Dokument.createElement('div');
}

Dann ist die setAttribute -Methode eigentlich sehr einfach. Verwenden Sie einfach this.root und rufen Sie setAttribute in der DOM-API auf. Dasselbe gilt für appendChild . Schließlich sieht unser Code wie folgt aus:

Klasse Div {
 // Konstruktor // DOM-Knoten erstellen konstruktor() {
 dies.root = Dokument.createElement('div');
 }
 // Die Attribute des Elements mounten setAttribute(name, attribute) {
 this.root.setAttribute(Name, Attribut);
 }
 // Element untergeordnetes Element mounten appendChild(child) {
 dies.root.appendChild(Kind);
 }
 // Das aktuelle Element mounten mountTo(parent) {
 übergeordnetes Element.anhängenKind(diese.Wurzel);
 }
}

Verpacken wir es mit Webpack, um die Wirkung zu sehen:

Wir können sehen, dass sowohl Div als auch Span erfolgreich am Body montiert sind. Es beweist auch, dass unser selbst erstelltes Div normal funktionieren kann.

Hier gibt es noch ein weiteres Problem, da wir schließlich a.mountTo() aufgerufen haben. Wenn unsere Variable a kein benutzerdefiniertes Element, sondern unser normales HTML-Element ist, verfügt sie zu diesem Zeitpunkt nicht über die Methode mountTo .

Deshalb müssen wir hier auch gewöhnlichen Elementen eine Wrapper-Klasse hinzufügen, damit sie das Standardformat unserer Elementklasse beibehalten können. Es wird auch als Standardschnittstelle bezeichnet.

Schreiben wir zunächst eine ElementWrapper -Klasse. Der Inhalt dieser Klasse ist im Grunde derselbe wie bei unserem Div. Es gibt nur zwei Unterschiede

Beim Erstellen eines DOM-Knotens können Sie den aktuellen type an unseren Konstruktor übergeben und diesen Typ zum Erstellen unseres DOM-Knotens verwenden. AppendChild kann this.root.appendChild nicht direkt verwenden, da alle normalen Tags in unsere benutzerdefinierte Klasse geändert werden. Daher muss die Logik von appendChild child.mountTo(this.root) geändert werden.

Klasse ElementWrapper {
 // Konstruktor // DOM-Knoten erstellen Konstruktor (Typ) {
 this.root = document.createElement(Typ);
 }
 // Die Attribute des Elements mounten setAttribute(name, attribute) {
 this.root.setAttribute(Name, Attribut);
 }
 // Element untergeordnetes Element mounten appendChild(child) {
 Kind.mountTo(diese.Wurzel);
 }
 // Das aktuelle Element mounten mountTo(parent) {
 übergeordnetes Element.anhängenKind(diese.Wurzel);
 }
}

Klasse Div {
 // Konstruktor // DOM-Knoten erstellen konstruktor() {
 dies.root = Dokument.createElement('div');
 }
 // Die Attribute des Elements mounten setAttribute(name, attribute) {
 this.root.setAttribute(Name, Attribut);
 }
 // Element untergeordnetes Element mounten appendChild(child) {
 Kind.mountTo(diese.Wurzel);
 }
 // Das aktuelle Element mounten mountTo(parent) {
 übergeordnetes Element.anhängenKind(diese.Wurzel);
 }
}

Wir haben hier immer noch ein Problem: Wenn wir auf einen Textknoten stoßen, wird dieser nicht in unsere benutzerdefinierte Klasse konvertiert. Deshalb müssen wir auch einen für den Textknoten schreiben, genannt TextWrapper .

Klasse TextWrapper {
 // Konstruktor // DOM-Knoten erstellen Konstruktor (Inhalt) {
 this.root = document.createTextNode(Inhalt);
 }
 // Die Attribute des Elements mounten setAttribute(name, attribute) {
 this.root.setAttribute(Name, Attribut);
 }
 // Element untergeordnetes Element mounten appendChild(child) {
 Kind.mountTo(diese.Wurzel);
 }
 // Das aktuelle Element mounten mountTo(parent) {
 übergeordnetes Element.anhängenKind(diese.Wurzel);
 }
}

Mit diesen Elementklassenschnittstellen können wir die Logik in unserem createElement neu schreiben. Ersetzen Sie einfach unsere ursprünglichen document.createElement und document.createTextNode durch die Instanziierung von new ElementWrapper(type) und new TextWrapper(content) .

Funktion createElement(Typ, Attribute, ...Kinder) {
 //Element erstellen let element;
 wenn (Typ von Typ === 'Zeichenfolge') {
 Element = neuer ElementWrapper(Typ);
 } anders {
 Element = neuer Typ();
 }

 //Attribute für (Name in Attributen lassen) aufhängen {
 element.setAttribute(name, Attribute[name]);
 }
 //Alle untergeordneten Elemente anhängen für (let child of children) {
 wenn (Typ des untergeordneten Elements === 'Zeichenfolge') 
		Kind = neuer TextWrapper(Kind);
 element.appendChild(Kind);
 }
 //Schließlich ist unser Element ein Knoten// also können wir direkt das Return-Element zurückgeben;
}

Dann verpacken wir es mit Webpack und sehen nach.

Es gibt keine Überraschungen, dass unser gesamtes Element normal am Körper montiert ist. Und wenn wir unser Div wieder in div ändern, funktioniert es auch ordnungsgemäß.

Natürlich schreiben wir grundsätzlich kein bedeutungsloses Div-Element. Hier schreiben wir den Namen unserer Komponente, beispielsweise Carousel , eine Komponente für ein Karussell.

Vollständiger Code – bitte geben Sie mir ein ⭐️, wenn Ihnen das hilft, danke!

Damit ist dieser Artikel über die Verwendung von JSX zum Erstellen eines Beispiels für die Entwicklung von Markup-Komponenten (Front-End-Komponentenbildung) abgeschlossen. Weitere verwandte JSX-Skripte, die Erstellung von JSX-Gruppenkomponenten und Inhalte im JSX-Stil finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die verwandten Artikel weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • So verwenden Sie die JSX-Syntax in Vue
  • Spezifische Verwendung der JSX-Syntax von Vue-Komponenten
  • Vue jsx-Nutzungshandbuch und Verwendung der jsx-Syntax in vue.js
  • Detaillierte Erklärung zur Verwendung von jsx zum Schreiben von Vue-Komponenten

<<:  MySQL-Fehler: Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktionslösung neu zu starten.

>>:  Anwendung von Hadoop-Zählern und Datenbereinigung

Artikel empfehlen

Zusammenfassung der Befehle zur Benutzerverwaltung im Linux-System

Benutzer- und Gruppenverwaltung 1. Grundlegende K...

WeChat-Applet implementiert Sortierfunktion basierend auf Datum und Uhrzeit

Ich habe vor kurzem ein kleines Programmierprojek...

MySQL-Daten einfügen, aktualisieren und löschen Details

Inhaltsverzeichnis 1. Einfügen 2. Aktualisierung ...

Schritte zur Erstellung einer React Fiber-Struktur

Inhaltsverzeichnis React-Fasererstellung 1. Bevor...

Detaillierte Einführung in den Nobody-Benutzer und Nologin im Unix/Linux-System

Was ist der Nobody-Benutzer in Unix/Linux-Systeme...

js, um die Funktion zum Hochladen von Bildern zu realisieren

Das Prinzip des Hochladens von Bildern auf dem Fr...

Zusammenfassung der für MySQL erforderlichen allgemeinen Kenntnisse

Inhaltsverzeichnis Primärschlüsseleinschränkung E...

Eine kurze Diskussion über Makrotasks und Mikrotasks in js

Inhaltsverzeichnis 1. Über JavaScript 2. JavaScri...

So löschen Sie den gesamten Inhalt eines Verzeichnisses mit Ansible

Studierende, die Ansible verwenden, wissen, dass ...

Ein genauerer Blick auf SQL-Injection

1. Was ist SQL-Injection? SQL-Injection ist eine ...