VorwortDie aktuellen Mainstream-Frameworks Vue und React werden beide über Virtual Dom implementiert, was die Effizienz der Seitendarstellung durch Virtual Dom-Technologie verbessert. In Vue schreiben wir HTML-Code in die Vorlage und in React schreiben wir HTML-Code in eine interne Renderfunktion. Nachdem diese Funktion durch jsx kompiliert wurde, gibt sie tatsächlich eine h-Funktion aus, die unser virtuelles Dom ist. Das Folgende ist eine einfache Implementierung eines virtuellen Doms, das ein reales Dom rendert, sowie die Update-Methode. ZielEs realisiert hauptsächlich die folgenden drei Funktionen:
Erster Schritt:Erstellen Sie einen Knoten mit der ID-App im Body-Tag. Der virtuelle Knoten wird später auf diesem Knoten bereitgestellt und renderer.js wird verwendet, um die oben genannten drei Funktionen zu implementieren. <Text> <div id="app"></div> <script src="./renderer.js"></script> </body> Schritt 2:Schreiben Sie die h-Funktion, um Tag (Tag-Element), Props (Eigenschaftsobjekt) und Kinder (untergeordnete Knoten) zurückzugeben. Einfach ausgedrückt ist der virtuelle Dom ein gewöhnliches JavaScript-Objekt. // renderer.js const h = (Tag, Requisiten, untergeordnete Elemente) => { zurückkehren { Etikett, Requisiten, Kinder } } Werfen wir also einen kurzen Blick auf die Ausgabe des folgenden Codes durch diese h-Funktion. const vdom = h("div", {Klasse: "Header"}, [ h("h2", null, "Hallo Welt"), h("h2", {id: 0}, h("span", null, "Spanne")) // Wenn die Eigenschaften keinen Wert haben, muss ein Nullwert übergeben werden, er kann nicht weggelassen werden]); Konsole.log(vdom); Wie aus der folgenden Abbildung ersichtlich ist, wird uns durch die h-Funktion ein JavaScript-Objekt zurückgegeben, bei dem es sich um den virtuellen Dom handelt, der einen Baumknoten bildet. Wie mounten wir also diese Vnodes zum realen Knoten? Schauen wir uns nun Schritt drei an. Schritt 3:Wir erstellen zunächst eine Mount-Funktion, die zwei Parameter übergeben muss. Der erste sind die Vnodes, die wir gerade über die h-Funktion zurückgegeben haben, und der zweite Parameter ist, auf welchem Knoten wir diese Vnodes mounten müssen. Sehen wir uns den Code an: const mount = (vnodes, app) => { // Erstellen Sie einen Knoten über den Tag-Wert in vnodes, z. B. („div“, „h2“) // Speichern Sie auch ein echtes DOM im vnodes-Objekt, um zukünftige Aktualisierungen, Ergänzungen usw. zu erleichtern. const el = vnodes.el = document.createElement(vnodes.tag); // Nachdem wir diesen Knoten erhalten haben, fügen wir Eigenschaften hinzu, indem wir den Props-Wert beurteilen, wenn (vnodes.props) { für (let-Schlüssel in vnodes.props) { // Hier treffen wir nach Erhalt des Schlüsselwerts in den Props eine Beurteilung: let value = vnodes.props[key]; wenn (Schlüssel.startetMit('ein')) { // Wenn der Benutzer beispielsweise onClick="changeData" schreibt, wird dies als Ereignislistenerfunktion verarbeitet el.addEventListener(key.slice(2).toLowerCase(), value) } anders { el.setAttribute(Schlüssel, Wert) } // Nachfolgend finden Sie einige Urteile, z. B. Anweisungen, v-if usw. für die Grenzverarbeitung} } // Nach der Verarbeitung der Eigenschaften ist der letzte Knoten Children if (vnodes.children) { wenn (Typ von vnodes.children === 'Zeichenfolge') { // Wenn dies ein String-Typ ist, können Sie ihn direkt zum Knoten el.textContent = vnodes.children hinzufügen. } anders { // In diesem Fall handelt es sich um einen Array-Typ, der untergeordnete Knoten enthält und dann durch Durchlauf untergeordnete Knoten generiert vnodes.children.forEach(vnode => { // Den untergeordneten Knoten rekursiv erneut in den aktuellen Knoten einhängen mount(vnode, el) }) } } //Mounten Sie abschließend diesen realen Knoten in dem App-Knoten, den wir in app.appendChild(el) übergeben haben. } const app = document.querySelector("#app") mount(vdom, app) Schauen wir uns die tatsächliche Auswirkung der Montage über die Mount-Funktion an: Bisher haben wir einen realen DOM durch einen virtuellen DOM erstellt. Wie aktualisieren wir diese DOMs in Vue? Als nächstes erstellen wir eine Patch-Funktion (Update): Schritt 4:Über die Patch-Funktion müssen wir zwei Parameter (vnodes1, vnodes2) übergeben, nämlich den neuen virtuellen Dom und den alten virtuellen Dom. Durch den Vergleich des neuen und des alten virtuellen Doms können wir angeben, welche Knoten aktualisiert werden sollen. (Der Schlüsselwert wird hier nicht berücksichtigt. Wenn Sie den Schlüsselwert benötigen, können Sie den Link überprüfen: https://www.jb51.net/article/219078.htm) //Patch-Funktion n1: alter Knoten, n2: neuer Knoten // Im Vue-Quellcode werden der alte und der neue Vnode jeweils durch n1 und n2 dargestellt const patch = (n1, n2) => { // Oben haben wir das Knotenattribut el über die Mount-Funktion zu n2 hinzugefügt und es an n2 gebunden const el = n2.el = n1.el // Beginnen Sie zunächst mit den Tags in den beiden if (n1.tag == n2.tag) { // n1 und n2 haben das gleiche Tag, dann vergleiche die Eigenschaften const n1Props = n1.props || {}; const n2Props = n2.props || {}; // Hole Props jeweils von n1 und n2 und vergleiche für (let key in n2Props) { // Alle Schlüssel in n2 herausnehmen und prüfen, ob der Schlüsselwert von n2 mit dem Schlüsselwert von n1 übereinstimmt const n1Value = n1Props[key] || ''; const n2Value = n2Props[Schlüssel] || ''; wenn (n1Wert !== n2Wert) { wenn (Schlüssel.startetMit('ein')) { // Wenn der Benutzer beispielsweise onClick="changeData" schreibt, wird dies als Event-Listener-Funktion verarbeitet el.addEventListener(key.slice(2).toLowerCase(), n2Value) } anders { el.setAttribute(Schlüssel, n2Wert) } } //Wenn sie gleich sind, wird keine Verarbeitung durchgeführt} für (let-Schlüssel in n1Props) { const alterWert = n1Props[Schlüssel]; if (!(Schlüssel in n2Props)) { wenn (Schlüssel.startetMit('ein')) { el.removeEventListener(Schlüssel.Slice(2).toLowerCase(), alterWert) } anders { el.removeAttribute(Schlüssel) } } } } anders { // Tag ist anders, hole den übergeordneten Knoten von n1 const n1Parent = n1.el.parentElement; // Entferne den alten Knoten vom übergeordneten Knoten durch removeChild und mounte dann n2 zum übergeordneten Knoten n1Parent.removeChild(n1.el); //n1.el ist der echte Dom-Knoten, der dem Objekt durch die Mount-Funktion mount(n2, n1Parent) hinzugefügt wurde. } // Zum Schluss verarbeiten wir die untergeordneten Elemente, was relativ kompliziert ist. // Untergeordnete Elemente können Zeichenfolgen oder Arrays sein, also schauen wir uns zuerst an, wie die Zeichenfolge verarbeitet wird. const n1Children = n1.children || []; const n2Children = n2.children || []; wenn (Typ von n2Children === "Zeichenfolge") { // Wenn der neue Knoteninhalt eine Zeichenfolge ist, verwenden Sie direkt innerhtml, um el.innerHtml = n2Children zu ersetzen. } anders { // Die folgende Situation ist, wenn n2.children ein Array ist, if (typeof n1.children === "string") { // n1.children ist ein String, n2.children ist ein Array el.innerHtml = ''; // Erst den Knoteninhalt prüfen, dann neuen Inhalt hinzufügen mount(n2.children, el) } anders { // Wenn beides Array-Typen sind, wird der Schlüsselwert hier nicht berücksichtigt const minLength = Math.min(n1Children.length, n2Children.length); für (sei i = 0; i < minLength; i++) { Patch(n1Kinder[i], n2Kinder[i]); } wenn (n2Kinder.Länge > n1Kinder.Länge) { n2Children.slice(minLength).fürJedes(Element => { einhängen(Artikel, el) }) } wenn (n2Kinder.Länge < n1Kinder.Länge) { n1Children.slice(minLength).fürJedes(Element => { el.entfernenKind(item.el) }) } } } } Das Obige ist eine einfache Implementierung der Patch-Funktion, die eigentlich das ist, was wir den Diff-Algorithmus nennen (natürlich wird der Schlüsselwert hier nicht berücksichtigt und es können nur zwei nacheinander verglichen werden), und der Vergleich wird auf derselben Ebene durchgeführt. Lassen Sie uns nun simulieren und demonstrieren, ob das Update erfolgreich sein kann: const vdom = h("div", {Klasse: "Header"}, [ h("h2", null, "Hallo Welt"), h("h2", {id: 0}, [h("span", null, "Spanne")]) // Wenn die Eigenschaften keinen Wert haben, muss ein Nullwert übergeben werden, er kann nicht weggelassen werden]); const app = document.querySelector("#app") mount(vdom, app) setTimeout(()=> { // Übergebe die neuen und alten Vnodes nach 3 Sekunden an den Patch const vdom1 = h("div", {Klasse: "Header"}, [ h("h3", null, "Hallo Welt"), h("span", null, "Spanne") ]) Patch(vdom, vdom1) },3000) Aus der folgenden Abbildung können wir erkennen, dass der virtuelle DOM-Updateknoten einfach implementiert wurde. ZusammenfassenEs implementiert einfach den virtuellen Dom, um echte Knoten zu generieren, und aktualisiert diese dann durch Patches. Wenn Sie sich den Quellcode noch einmal ansehen, können Sie besser verstehen, wie der Renderer von Vue implementiert ist. Dies ist das Ende dieses Artikels über die einfache Implementierung von Mini-Vue-Rendering. Weitere relevante Inhalte zum Mini-Vue-Rendering finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
>>: Methode und Einführung der Tabellenindexdefinition in MySQL
1. Verwendung von Pseudonymen Mit dem Alias-Befeh...
Inhaltsverzeichnis 1. Einleitung 2. Bereiten Sie ...
CentOS 6 und frühere Versionen stellen MySQL-Serv...
Nachdem ich React eine Weile studiert habe, möcht...
Der folgende Code befindet sich in meiner test.htm...
Ich habe die vorherigen Hinweise zur Installation...
In diesem Artikelbeispiel wird der spezifische Im...
Vorwort Nehmen Sie Element Plus als Beispiel, um ...
Einführung in jsvc In der Produktion sollte Tomca...
Erstellen einer Tabelle CREATE TABLE `map` ( `id`...
Inhaltsverzeichnis Einführung in das Decorator-Mu...
Ansible ist ein neues, auf Python basierendes, au...
Studiennotizen zu HTML-Entwurfsmustern Diese Woch...
Ich habe vor kurzem Porter gelernt. Ich habe das ...
Die Rolle der Schnittstelle: Schnittstelle, auf E...