1. Grundlegende VerwendungOffizielle Website Fall: <div id='App'> <Eingabetyp="Text" v-Modell="Eingabewert" v-Fokus> </div> <Skript> Vue.direktive('Fokus', { // Rufe bind() auf, wenn du ein Element zum ersten Mal bindest { console.log('binden') }, // Wenn das gebundene Element in das DOM eingefügt wird ... eingefügt: Funktion (el) { console.log('eingefügt') el.fokus() }, // Rufe update() auf, wenn die Komponente VNode aktualisiert ist { console.log('aktualisieren') }, // Rufen Sie componentUpdated() auf, nachdem alle VNode und seine untergeordneten VNodes der Komponente, in der sich die Anweisung befindet, aktualisiert wurden { console.log('Komponente aktualisiert') }, // Wird nur einmal aufgerufen. unbind() wird aufgerufen, wenn die Anweisung vom Element { gelöst wird. console.log('aufheben') } }) neuer Vue({ Daten: { Eingabewert: '' } }).$mount('#app') </Skript> 2. Funktionsweise der Anweisungen2.1. InitialisierungRufen Sie beim Initialisieren der globalen API unter Plattformen/Web die Funktion createPatchFunction auf, um die Patch-Methode zu generieren, die VNode in das echte DOM konvertiert. Ein wichtiger Schritt bei der Initialisierung ist die Definition der Hook-Methoden, die den DOM-Knoten entsprechen. Während der Erstellung (create), Aktivierung (avtivate), Aktualisierung (update), Entfernung (remove) und Zerstörung (destroy) des DOM werden die entsprechenden Hook-Methoden abgefragt und jeweils aufgerufen. Einige dieser Hooks sind die Eingänge zum Befehlsdeklarationszyklus. // src/core/vdom/patch.js const hooks = ['erstellen', 'aktivieren', 'aktualisieren', 'entfernen', 'zerstören'] Exportfunktion createPatchFunction (Backend) { sei i, j const cbs = {} const { module, nodeOps } = backend für (i = 0; i < hooks.length; ++i) { cbs[Haken[i]] = [] // Module entsprechen Modulen in Vue, einschließlich Klasse, Stil, DomListener, DomProps, Attrs, Direktive, Ref, Übergang für (j = 0; j < Module.Länge; ++j) { wenn (isDef(Module[j][Hooks[i]])) { // Schließlich Hooks in {hookEvent: [cb1, cb2 ...], ...} von cbs[hooks[i]].push(modules[j][hooks[i]]) umwandeln. } } } // .... Rückgabefunktionspatch (alterVnode, vnode, hydratisieren, nur entfernen) { // ... } } 2.2 VorlagenkompilierungDie Vorlagenkompilierung dient zum Parsen der Anweisungsparameter. Das spezifische dekonstruierte ASTElement lautet wie folgt: { Tag: 'Eingabe', übergeordnetes Element: ASTElement, Anweisungen: [ { arg: null, // Parameterende: 56, // Endzeichenposition der Anweisung isDynamicArg: false, // dynamischer Parameter, v-xxx[dynamicParams]='xxx' Formaufrufmodifikatoren: nicht definiert, // Name des Anweisungsmodifikators: „model“, rawName: "v-model", // Befehlsname Start: 36, // Befehlsstartzeichenposition Wert: "inputValue" // Vorlage }, { arg: null, Ende: 67, isDynamicArg: false, Modifikatoren: undefiniert, Name: "Fokus", Rohname: "v-focus", Beginn: 57, Wert: "" } ], // ... } 2.3. Rendering-Methode generierenVue empfiehlt die Verwendung von Anweisungen zum Bedienen von DOM. Da benutzerdefinierte Anweisungen DOM oder Attribute ändern können, vermeiden Sie die Auswirkungen von Anweisungen auf die Vorlagenanalyse. Beim Generieren von Rendering-Methoden müssen zuerst Anweisungen wie v-model verarbeitet werden, was im Wesentlichen ein syntaktischer Zucker ist. Beim Spleißen von Rendering-Funktionen werden den Elementen Wertattribute und Eingabeereignisse hinzugefügt (am Beispiel der Eingabe kann dies auch vom Benutzer angepasst werden). mit (diesem) { return _c('div', { Attribute: { "id": "App" } }, [_c('Eingabe', { Anweisungen: [{ Name: "Modell", rawName: "v-Modell", Wert: (Eingabewert), Ausdruck: "Eingabewert" }, { Name: "Fokus", Rohname: "v-focus" }], Attribute: { "Typ": "Text" }, domProps: { "value": (inputValue) // Attribute, die bei der Verarbeitung von v-model-Anweisungen hinzugefügt werden}, An: { "input": function($event) { // Benutzerdefiniertes Ereignis, das bei der Verarbeitung der V-Model-Direktive hinzugefügt wird, wenn ($event.target.composing) zurückkehren; Eingabewert = $event.target.value } } })]) } 2.4. VNode generierenDas Design der Vue-Anweisungen soll unseren DOM-Betrieb erleichtern. Beim Generieren von VNode führen die Anweisungen keine zusätzlichen Verarbeitungsvorgänge aus. 2.5. Echtes DOM generierenWährend des Vue-Initialisierungsprozesses müssen wir zwei Punkte beachten:
Während des Patch-Prozesses wird jedes Mal, wenn createElm aufgerufen wird, um das echte DOM zu generieren, festgestellt, ob der aktuelle VNode ein Datenattribut hat. Wenn dies der Fall ist, wird invokeCreateHooks aufgerufen, um die am Anfang erstellte Hook-Funktion auszuführen. Der Kerncode lautet wie folgt: // src/core/vdom/patch.js Funktion createElm ( vKnoten, eingefügteVnodeQueue, übergeordnete Ulme, sieheElm, verschachtelt, BesitzerArray, Index ) { // ... // createComponent hat einen Rückgabewert, also die Methode zum Erstellen von Komponenten. Wenn es keinen Rückgabewert gibt, fahren Sie mit der folgenden Methode fort, if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { zurückkehren } const data = vnode.data // .... wenn (isDef(Daten)) { // Nachdem der reale Knoten erstellt wurde, aktualisiere die Knotenattribute, einschließlich der Anweisung // Die Anweisung ruft die Bind-Methode zum ersten Mal auf und initialisiert dann die nachfolgende Hook-Methode der Anweisung invokeCreateHooks(vnode, insertedVnodeQueue) } // Von unten nach oben, einfügen(parentElm, vnode.elm, refElm) // ... } Oben sehen Sie den ersten Eintrag der Direktiven-Hook-Methode. Es ist an der Zeit, das Geheimnis von // src/core/vdom/modules/directives.js // Standardmäßig sind alle ausgelösten Methoden updateDirectives method export default { erstellen: updateDirectives, aktualisieren: Update-Richtlinien, zerstören: Funktion unbindDirectives (vnode: VNodeWithData) { // Wenn zerstört, vnode === emptyNode Update-Direktiven(vnode, leererKnoten) } } Funktion updateDirectives (alter Vnode: VNodeWithData, vnode: VNodeWithData) { wenn (alteVnode.data.directives || vnode.data.directives) { _update(alterVnode, vnode) } } Funktion _update (alterVnode, vnode) { const isCreate = alterVnode === leererNode const isDestroy = vnode === leerer Knoten const oldDirs = normalizeDirectives(alterVnode.data.directives, alterVnode.context) const newDirs = normalizeDirectives(vnode.data.directives, vnode.context) // Rückruf nach dem Einfügen const dirsWithInsert = [ // Rückruf nach Abschluss des Updates const dirsWithPostpatch = [] let-Schlüssel, oldDir, dir für (Schlüssel in newDirs) { oldDir = oldDirs[Schlüssel] dir = newDirs[Schlüssel] // Neuer Elementbefehl, führt die eingefügte Hook-Methode einmal aus, wenn (!oldDir) { // neue Direktive, binden callHook(dir, 'binden', vnode, alter Vnode) if (dir.def && dir.def.inserted) { dirsWithInsert.push(dir) } } anders { // bestehende Direktive, Update // Wenn das Element bereits existiert, wird die componentUpdated-Hook-Methode dir.oldValue = oldDir.value einmal ausgeführt dir.oldArg = altesDir.arg callHook(dir, 'update', vnode, alter vnode) wenn (dir.def && dir.def.componentUpdated) { dirsWithPostpatch.push(dir) } } } if (dirsWithInsert.length) { // Das echte DOM wird in die Seite eingefügt und diese Callback-Methode wird aufgerufen const callInsert = () => { für (lass i = 0; i < dirsWithInsert.length; i++) { callHook(dirsWithInsert[i], 'eingefügt', vnode, alterVnode) } } // VNode Merge-Insert-Hooks wenn (ist erstellt) { mergeVNodeHook(vnode, 'insert', callInsert) } anders { callInsert() } } if (dirsWithPostpatch.Länge) { mergeVNodeHook(vnode, 'postpatch', () => { für (lass i = 0; i < dirsWithPostpatch.length; i++) { callHook(dirsWithPostpatch[i], 'Komponente aktualisiert', vnode, alter Vnode) } }) } wenn (!istErstellen) { für (Schlüssel in oldDirs) { wenn (!newDirs[Schlüssel]) { // nicht mehr vorhanden, Bindung aufheben callHook(alteDirs[Schlüssel], 'aufheben', alterV-Knoten, alterV-Knoten, isDestroy) } } } } Bei der ersten Erstellung läuft die Ausführung folgendermaßen ab: 1.oldVnode === emptyNode, isCreate ist true und alle Bind-Hook-Methoden im aktuellen Element werden aufgerufen. 2. Überprüfen Sie, ob die Anweisung einen eingefügten Hook enthält. Wenn ja, fügen Sie den eingefügten Hook in die Eigenschaft VNode.data.hooks ein. 3. Nachdem die DOM-Montage abgeschlossen ist, wird invokeInsertHook für alle montierten Knoten ausgeführt, wenn in VNode.data.hooks ein Einfüge-Hook vorhanden ist. Es wird aufgerufen und die an die Anweisung gebundene eingefügte Methode wird ausgelöst. Im Allgemeinen werden für die erste Erstellung nur die Methoden „Bind“ und „Insert“ verwendet, während „Update“ und „ComponentUpdated“ den Methoden „Bind“ und „Insert“ entsprechen. Wenn sich der Abhängigkeitsstatus der Komponente ändert, wird der VNode-Diff-Algorithmus zum Patchen des Knotens verwendet. Der Aufrufvorgang läuft wie folgt ab: 1. Wenn sich die Reaktionsdaten ändern, rufen Sie dep.notify auf, um über Datenaktualisierungen zu benachrichtigen. 2. Rufen Sie patchVNode auf, um differenzielle Aktualisierungen an den neuen und alten VNodes durchzuführen und die aktuellen VNode-Attribute vollständig zu aktualisieren (einschließlich Anweisungen, die in die Methode updateDirectives gelangen). 3. Wenn die Anweisung über eine Update-Hook-Methode verfügt, rufen Sie die Update-Hook-Methode auf, initialisieren Sie den ComponentUpdated-Rückruf und mounten Sie die Postpatch-Hooks in VNode.data.hooks. 4. Nachdem der aktuelle Knoten und seine untergeordneten Knoten aktualisiert wurden, werden die Postpatch-Hooks ausgelöst, dh die componentUpdated-Methode der Anweisung Der Kerncode lautet wie folgt: // src/core/vdom/patch.js Funktion patchVnode ( alterVnode, vKnoten, eingefügteVnodeQueue, BesitzerArray, Index, Nur entfernen ) { // ... const oldCh = oldVnode.children const ch = vnode.children // Knotenattribute vollständig aktualisieren if (isDef(data) && isPatchable(vnode)) { für (i = 0; i < cbs.update.length; ++i) cbs.update[i](alterVnode, vnode) wenn (isDef(i = data.hook) und isDef(i = i.update)) i(alterVnode, vnode) } // ... wenn (isDef(Daten)) { // Postpatch-Hook aufrufen, wenn (isDef(i = data.hook) und isDef(i = i.postpatch)) i(oldVnode, vnode) } } Die Methode „unbind“ ruft „invokeDestroyHook“ auf, wenn der Knoten zerstört wird. Dies wird hier nicht näher beschrieben. 3. HinweiseBei der Verwendung benutzerdefinierter Anweisungen weist das V-Modell noch einige Unterschiede zur normalen Datenbindung von Vorlagen auf. Obwohl beispielsweise der von mir übergebene Parameter (v-xxx = 'param') ein Referenztyp ist, kann er bei Datenänderungen weder das Binden noch das Einfügen der Anweisung auslösen. Dies liegt daran, dass im Deklarationszyklus der Anweisung Binden und Einfügen nur einmal bei der Initialisierung aufgerufen werden und danach nur Update und ComponentUpdated verwendet werden. Die Ausführungsreihenfolge im Deklarationslebenszyklus einer Direktive lautet binden -> eingefügt -> aktualisieren -> componentUpdated. Wenn eine Direktive vom Inhalt einer untergeordneten Komponente abhängen muss, wird empfohlen, die entsprechende Geschäftslogik in componentUpdated zu schreiben. In Vue werden viele Methoden in einer Schleife aufgerufen, z. B. Hook-Methoden, Event-Callbacks usw. Im Allgemeinen werden die Aufrufe in Try-Catch gekapselt. Dies soll verhindern, dass eine Verarbeitungsmethode einen Fehler meldet und das gesamte Programm zum Absturz bringt. Dies kann als Referenz in unserem Entwicklungsprozess verwendet werden. IV. ZusammenfassungAls ich begann, mir den gesamten Vue-Quellcode anzusehen, wusste ich über viele Details und Methoden nicht viel. Indem ich die Implementierung jeder einzelnen Funktion klärte, konnte ich mir allmählich ein Gesamtbild von Vue verschaffen und gleichzeitig einige Fallstricke bei der Entwicklung und Verwendung vermeiden. Oben finden Sie den detaillierten Inhalt der Analyse des Implementierungsprinzips der Vue-Direktive. Weitere Informationen zum Prinzip der Vue-Direktive finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung der MySQL-Remoteverbindungsberechtigung
>>: Detaillierte Erläuterung der Installationsschritte der dekomprimierten MySQL-Version
Inhaltsverzeichnis Installieren Sie den Vim-Plugi...
Vorwort In diesem Artikel wird hauptsächlich ein ...
CHAR- und VARCHAR-Typen sind ähnlich und untersch...
Das Entwerfen der Navigation für eine Website ist...
1. Erstellen Sie ein Centos7.6-System und optimie...
Inhaltsverzeichnis Blasensortierung Auswahl Sorti...
Dieser Artikel beschreibt anhand eines Beispiels,...
Inhaltsverzeichnis Vorwort 1. Vorschau der Office...
Wenn Sie das Breitenattribut direkt auf den Stil d...
einführen Haben Sie schon einmal einen ganzen Tag...
Inhaltsverzeichnis 1. Standardwerte für Funktions...
Mauseffekte erfordern die Verwendung von setTimeo...
Ich habe gerade angefangen, React für Projekte zu...
Dieser Artikel stellt den Import und Export von D...
Inhaltsverzeichnis 1. Listendurchlauf 2. Die Roll...