Virtueller DOM Was ist virtueller DomDOM ist ein Dokumentobjektmodell, das Dokumente in Form eines Knotenbaums darstellt. Virtueller DOM ist kein echter DOM. Es handelt sich vielmehr um ein Javascript-Objekt. Ein normaler DOM-Knoten wird in HTML wie folgt dargestellt: <div Klasse='Test-ID'> <p>Hallo</p> <p>Willkommen</p> </div> Im virtuellen DOM sieht es folgendermaßen aus: { Tag: 'div', Attribute: Klasse: ['Test-ID'] }, Kinder:[ // p-Element // p-Element] } Zum besseren Verständnis können wir den virtuellen Dom in zwei Teile aufteilen: virtuell + Dom.
Die Rolle des virtuellen DomsDie aktuellen Mainstream-Frameworks sind alle Frameworks für deklarative DOM-Operationen. Wir müssen nur die Zuordnungsbeziehung zwischen dem Status und dem DOM beschreiben. Das Framework hilft uns dabei, den Status in die Ansicht (das echte DOM) zu konvertieren. Der einfachste Ansatz besteht darin, den Status in einer Ansicht darzustellen und die gesamte Ansicht bei jeder Aktualisierung des Status zu aktualisieren. Die Leistung dieses Ansatzes kann man sich vorstellen. Eine bessere Idee ist: Wenn sich der Status ändert, werden nur die mit dem Status verbundenen DOM-Knoten aktualisiert. Virtueller DOM ist nur eine Möglichkeit, diese Idee umzusetzen. Konkrete Schritte:
Wenn sich der Status ändert, wird ein neuer virtueller DOM generiert, der vorherige mit diesem verglichen, die Teile gefunden, die aktualisiert werden müssen, und der reale DOM wird aktualisiert. Virtueller DOM in VueDas reale Dom besteht aus Knoten (Node) und das virtuelle Dom besteht aus virtuellen Knoten (vNode). Der virtuelle DOM erledigt in Vue hauptsächlich zwei Aufgaben:
vNode Was ist vNodeWie oben erwähnt, entspricht vNode (virtueller Knoten) dem realen Knoten (Node). vNode kann als Knotenbeschreibungsobjekt verstanden werden. Beschreibt, wie man tatsächliche DOM-Knoten erstellt Es gibt eine vNode-Klasse in vue.js. Damit können verschiedene Typen von vNode-Instanzen erstellt werden. Verschiedene Typen von vNodes entsprechen verschiedenen Typen von DOM-Elementen. Der Code lautet wie folgt: exportiere Standardklasse VNode { Konstruktor ( Tag?: Zeichenfolge, Daten?: VNodeData, Kinder?: ?Array<VNode>, Text?: Zeichenfolge, Ulme?: Knoten, Kontext?: Komponente, Komponentenoptionen?: VNodeComponentOptions, asyncFactory?: Funktion ) { this.tag = Tag this.data = Daten this.children = Kinder dieser.text = Text diese.ulme = Ulme this.ns = undefiniert this.context = Kontext this.fnContext = nicht definiert this.fnOptions = nicht definiert this.fnScopeId = nicht definiert dieser.Schlüssel = Daten && Daten.Schlüssel this.componentOptions = Komponentenoptionen this.componentInstance = nicht definiert this.parent = undefiniert this.raw = falsch this.isStatic = falsch this.isRootInsert = true this.isComment = false this.isCloned = falsch this.isOnce = falsch this.asyncFactory = asyncFactory this.asyncMeta = nicht definiert this.isAsyncPlaceholder = falsch } hol Kind (): Komponente | void { gib diese.Komponenteninstanz zurück } } Aus dem Code lässt sich leicht erkennen, dass die von der vNode-Klasse erstellte Instanz im Wesentlichen ein gewöhnliches JavaScript-Objekt ist. Typ des vNodeWir haben bereits vorgestellt, dass mit der vNode-Klasse verschiedene Arten von vNodes erstellt werden können. Verschiedene vNode-Typen werden durch gültige Attribute unterschieden. Beispielsweise weist „isComment = true“ auf einen Kommentarknoten hin, „isCloned = true“ auf einen geklonten Knoten usw. Zu den vNode-Typen gehören: Kommentarknoten, Textknoten, Klonknoten, Elementknoten und Komponentenknoten. Hier sind die Codes für Kommentarknoten, Textknoten und Klonknoten: /* Gültige Attribute des Kommentarknotens: {isComment: true, text: ‚Kommentarknoten‘} */ export const createEmptyVNode = (text: Zeichenfolge = '') => { const node = neuer VNode() node.text = Text // Kommentar node.isComment = true Rückgabeknoten } /* Gültige Attribute von Textknoten: {text: 'text node'} */ Exportfunktion createTextVNode (Wert: Zeichenfolge | Zahl) { gibt neuen VNode zurück (undefiniert, undefiniert, undefiniert, String(val)) } // optimierter flacher Klon // wird für statische Knoten und Slot-Knoten verwendet, da sie wiederverwendet werden können // Für statische Knoten und Slot-Knoten // mehrere Renderings, das Klonen vermeidet Fehler, wenn DOM-Manipulationen darauf angewiesen sind // auf ihrer Ulmenreferenz. // Knoten klonen - Exportfunktion cloneVNode (vnode: VNode): VNode { const geklont = neuer VNode( vnode.tag, vnode.data, //#7975 // Untergeordnetes Array klonen, um eine Mutation des Originals beim Klonen zu vermeiden // ein Kind. vnode.children und vnode.children.slice(), vnode.text, vnode.elm, vnode.kontext, vnode.componentOptions, vnode.asyncFactory ) geklont.ns = vnode.ns geklont.isStatic = vnode.isStatic geklonter Schlüssel = vnode.key geklont.isComment = vnode.isComment geklont.fnContext = vnode.fnContext geklont.fnOptionen = vnode.fnOptionen geklont.fnScopeId = vnode.fnScopeId geklont.asyncMeta = vnode.asyncMeta // Markiere den Knoten als geklont.isCloned = true Rückkehr geklont } Durch das Klonen eines Knotens werden dem neuen Knoten tatsächlich alle Eigenschaften des vorhandenen Knotens zugewiesen, und schließlich wird er selbst mit Elementknoten haben normalerweise die folgenden vier Attribute:
Komponentenknoten ähneln Elementknoten und verfügen über zwei eindeutige Eigenschaften:
PatchWir haben bereits die erste Aufgabe des virtuellen DOM in Vue vorgestellt: das Bereitstellen eines virtuellen Knotens (vNode), der dem realen Knoten (Node) entspricht. Als Nächstes werden wir die zweite Aufgabe vorstellen: das Vergleichen des neuen virtuellen Knotens mit dem alten virtuellen Knoten, das Ermitteln der Unterschiede und anschließende Aktualisieren der Ansicht. Die zweite in Vue implementierte Sache heißt Patch, was Patchen oder Reparieren bedeutet. Durch Vergleichen der alten und neuen vNodes, Ermitteln der Unterschiede und anschließendes Patchen basierend auf dem vorhandenen DOM wird die Ansicht aktualisiert. Das Vergleichen von vNodes zum Auffinden von Unterschieden ist ein Mittel, und das Aktualisieren der Ansicht ist das Ziel. Das Aktualisieren einer Ansicht ist nichts anderes als das Hinzufügen, Löschen und Aktualisieren von Knoten. Als Nächstes analysieren wir nacheinander, wann und wo ein Knoten hinzugefügt werden soll; wann ein Knoten gelöscht werden soll und welcher gelöscht werden soll; wann ein Knoten aktualisiert werden soll und welcher aktualisiert werden soll; Hinweis: Wenn vNode und oldVNode unterschiedlich sind, hat vNode Vorrang. Einen neuen Knoten hinzufügenEine Situation ist: Wenn vNode vorhanden ist, aber oldVNode nicht existiert, muss ein neuer Knoten hinzugefügt werden. Am typischsten ist das anfängliche Rendering, da der odlVNode nicht existiert. Ein anderer Fall ist, dass vNode und oldVNode überhaupt nicht derselbe Knoten sind. Zu diesem Zeitpunkt müssen Sie vNode verwenden, um einen echten Dom-Knoten zu generieren und ihn neben dem echten Dom-Knoten einzufügen, auf den oldVNode zeigt. oldVNode ist ein verlassener Knoten. Beispielsweise in der folgenden Situation: <div> <p v-if="Typ === 'A'"> Ich bin Knoten A </p> <span v-else-if="Typ === 'B'"> Ich bin ein völlig anderer Knoten B als A </span> </div> Wenn sich der Typ von A nach B ändert, ändert sich der Knoten von p nach span. Da vNode und oldVNode überhaupt nicht derselbe Knoten sind, muss ein neuer Knoten hinzugefügt werden. Löschen eines KnotensWenn der Knoten nur im alten VNode vorhanden ist, löschen Sie ihn einfach. Knoten aktualisierenIm vorherigen Abschnitt haben wir die Szenarien zum Hinzufügen neuer Knoten und Löschen von Knoten vorgestellt. Wir haben festgestellt, dass sie eines gemeinsam haben: vNode ist völlig anders als oldVNode. Ein häufigeres Szenario ist jedoch, dass vNode und oldVNode derselbe Knoten sind. Dann müssen wir einen detaillierteren Vergleich zwischen ihnen (vNode und oldVNode) durchführen und dann den realen Knoten aktualisieren, der oldVNode entspricht. Für Textknoten ist die Logik natürlich einfach. Vergleichen Sie zunächst die alten und neuen vNodes und stellen Sie fest, dass es sich um denselben Knoten handelt. Ändern Sie dann den Text des Dom-Knotens, der dem alten VNode entspricht, in den Text im vNode. Bei komplexen vNodes, wie etwa einer Baumkomponente in der Schnittstelle, wird dieser Vorgang jedoch kompliziert. Neuer Knoten - QuellcodeanalyseDenken Sie darüber nach: Wie bereits erwähnt, gibt es die Typen von vNode: Kommentarknoten, Textknoten, Klonknoten, Elementknoten und Komponentenknoten. Werden alle dieser Typen erstellt und in das DOM eingefügt? Antwort: Nur Kommentarknoten, Textknoten und Elementknoten. Weil HTML nur diese Typen erkennt. Da es oben nur die drei Knotentypen gibt, erstellen Sie die entsprechenden Knoten entsprechend den Typen und fügen Sie sie dann an den entsprechenden Positionen ein. Nehmen wir Elementknoten als Beispiel: Wenn vNode ein Tag-Attribut hat, bedeutet dies, dass es sich um einen Elementknoten handelt. Die Methode createElement wird aufgerufen, um den entsprechenden Knoten zu erstellen, und dann wird die Methode appendChild verwendet, um ihn in den angegebenen übergeordneten Knoten einzufügen. Wenn das übergeordnete Element bereits angezeigt wird, wird es beim Einfügen des darunter liegenden Elements automatisch gerendert. Wenn die Eigenschaft isComment von vNode „true“ ist, weist dies auf einen Kommentarknoten hin. Wenn keines von beiden „true“ ist, weist dies auf einen Textknoten hin. Normalerweise gibt es im Element untergeordnete Knoten, sodass hier ein rekursiver Prozess beteiligt ist, d. h., die untergeordneten Knoten im vNode werden nacheinander durchlaufen, Knoten erstellt und diese dann rekursiv Schicht für Schicht in den übergeordneten Knoten eingefügt (der übergeordnete Knoten ist der soeben erstellte DOM-Knoten). Bitte sehen Sie sich den Quellcode an: // Elementfunktion erstellen createElm ( vKnoten, eingefügteVnodeQueue, übergeordnete Ulme, sieheElm, verschachtelt, BesitzerArray, Index ) { wenn (isDef(vnode.elm) und isDef(ownerArray)) { // Dieser Vnode wurde in einem vorherigen Render verwendet! // jetzt wird es als neuer Knoten verwendet, das Überschreiben seiner Ulme würde dazu führen // mögliche Patch-Fehler später, wenn es als Einfügung verwendet wird // Referenzknoten. Stattdessen klonen wir den Knoten bei Bedarf, bevor wir ihn erstellen // zugehöriges DOM-Element dafür. vnode = BesitzerArray[index] = Klon-VNode(vnode); } vnode.isRootInsert = !nested; // für Übergang Check eingeben wenn (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { zurückkehren } var Daten = vnode.data; var Kinder = vnode.Kinder; var tag = vnode.tag; // Hat ein Tag-Attribut, das angibt, dass es sich um einen Elementknoten handelt, if (isDef(tag)) { vnode.elm = vnode.ns ? nodeOps.createElementNS(vnode.ns, tag) //Erstellen Sie das Element. nodeOps ist plattformübergreifend: nodeOps.createElement(tag, vnode); setScope(vnode); /* istanbul ignorieren wenn */ { // Unterknoten rekursiv erstellen und in den übergeordneten Knoten einfügen createChildren(vnode, children, insertedVnodeQueue); wenn (isDef(Daten)) { invokeCreateHooks(vnode, insertedVnodeQueue); } //Füge das dem vnode entsprechende Element in das übergeordnete Element ein insert(parentElm, vnode.elm, refElm); } // isComment-Eigenschaft gibt einen Kommentarknoten an} else if (isTrue(vnode.isComment)) { vnode.elm = nodeOps.createComment(vnode.text); //Übergeordneten Knoten einfügeninsert(parentElm, vnode.elm, refElm); // Sonst ist es ein untergeordneter Knoten} else { vnode.elm = nodeOps.createTextNode(vnode.text); //Übergeordneten Knoten einfügeninsert(parentElm, vnode.elm, refElm); } } // Untergeordnete Knoten rekursiv erstellen und in den übergeordneten Knoten einfügen. vnode stellt den übergeordneten Knoten dar. Funktion createChildren (vnode, children, insertedVnodeQueue) { wenn (Array.isArray(Kinder)) { wenn (Prozess.Umgebung.NODE_ENV !== 'Produktion') { checkDuplicateKeys(untergeordnete Elemente); } //Erstelle nacheinander untergeordnete Knoten und füge sie in den übergeordneten Knoten ein for (var i = 0; i < children.length; ++i) { createElm(Kinder[i], eingefügteVnodeQueue, vnode.elm, null, true, Kinder, i); } } sonst wenn (isPrimitive(vnode.text)) { nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text))); } } Löschen eines Knotens - QuellcodeanalyseDas Löschen eines Knotens ist sehr einfach. Schauen Sie sich den Quellcode direkt an: // Einen Satz angegebener Knoten löschen function removeVnodes (parentElm, vnodes, startIdx, endIdx) { für (; startIdx <= endIdx; ++startIdx) { var ch = vnodes[startIdx]; wenn (isDef(ch)) { if (isDef(ch.tag)) { entfernenAndInvokeRemoveHook(ch); invokeDestroyHook(ch); } sonst { // Textknoten // Einen Knoten löschenremoveNode(ch.elm); } } } } // Einen einzelnen Knoten löschen Funktion removeNode (el) { var parent = nodeOps.parentNode(el); // Element wurde möglicherweise aufgrund von v-html / v-text bereits entfernt wenn (isDef(übergeordnet)) { // nodeOps kapselt die plattformübergreifende Methode nodeOps.removeChild(parent, el); } } Oben finden Sie den detaillierten Inhalt der Schnellstartanleitung für Vue Virtual DOM. Weitere Informationen zu Vue Virtual DOM finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Eine kurze Analyse des Unterschieds zwischen FIND_IN_SET() und IN in MySQL
>>: Installieren Sie Memcached und die PHP Memcached-Erweiterung unter CentOS
Umfeld: 1 CentOS Linux-Version 7.5.1804 (Core) Fi...
Das Betriebssystem Win10 MySQL ist die 64-Bit-ZIP...
In diesem Artikel wird der spezifische Code von V...
veranschaulichen: Stamm und Alias im Standort D...
Ich habe vor kurzem ein kleines Programmierprojek...
Informationen zum Deinstallieren der zuvor instal...
Obwohl das W3C einige Standards für HTML festgeleg...
Wissenspunkte in der Vorschau anzeigen. Animation...
Dokumentation zur Zabbix-Bereitstellung Nach der ...
Installation mithilfe des MSI-Installationspakets...
MySQL-Anweisungen zum Hinzufügen, Löschen, Ändern...
Vorwort Wenn wir einen MySQL-Cluster erstellen, m...
1. Blockebenenelement: bezieht sich auf die Fähigk...
Der Fehler „mysql ist kein interner Befehl“ tritt...
Inhaltsverzeichnis 1. Definition des Stapels 2. J...