1. EinleitungDieser Artikel ist für Anfänger geeignet, die den Vue-Quellcode lernen. Nach der Lektüre haben Sie ein allgemeines Verständnis des Prinzips der bidirektionalen Datenbindung in Vue und verstehen die drei Hauptrollen von Observer, Compile und Wathcer (wie in der folgenden Abbildung dargestellt) und ihre Funktionen. In diesem Artikel werden Sie Schritt für Schritt durch die Implementierung einer einfachen Version der bidirektionalen Datenbindung geführt. In jedem Schritt wird das in diesem Schritt zu lösende Problem und der Grund für die Art und Weise, wie der Code geschrieben wird, detailliert analysiert. Daher hoffe ich, dass Sie nach dem Lesen dieses Artikels selbst eine einfache Version der bidirektionalen Datenbindung implementieren können. 2. Code-Implementierung 2.1 ZweckanalyseDer mit diesem Artikel zu erzielende Effekt ist in der folgenden Abbildung dargestellt: Die in diesem Artikel verwendeten HTML- und JS-Hauptcodes sind wie folgt: <div id="app"> <h1 v-text="msg"></h1> <Eingabetyp="Text" v-Modell="Nachricht"> <div> <h1 v-text="msg2"></h1> <Eingabetyp="text" v-modell="msg2"> </div> </div> lass vm = neues Vue({ el: "#app", Daten: { Nachricht: "Hallo Welt", msg2: „hallo xiaofei“ } }) Dazu gehen wir in drei Schritten vor:
2.2 Implementierungsprozess 2.2.1 ZugangscodeZuerst müssen wir eine Vue-Klasse erstellen, die ein Optionsobjekt empfängt. Gleichzeitig müssen wir die gültigen Informationen im Optionsobjekt speichern. Dann haben wir drei Hauptmodule: Observer, Compile und Wathcer. Unter ihnen wird Observer zum Daten-Hijacking verwendet, Compile wird zum Parsen von Elementen verwendet und Wathcer ist ein Beobachter. Sie können den folgenden Code schreiben: (Es ist nicht erforderlich, die drei Konzepte Observer, Compile und Wathcer im Detail zu studieren, da sie später ausführlich erläutert werden.) Klasse Vue { // Empfange das übergebene Objekt Konstruktor(Optionen) { // Gültige Informationen speichern this.$el = document.querySelector(options.el); dies.$data = Optionen.data; //Container: {Attribut 1: [wathcer1, wathcer2...], Attribut 2: [...]}, wird zum Speichern jedes Attributbeobachters verwendet. $watcher = {}; // Elemente analysieren: Implementieren von Compile this.compile(this.$el); // Um das Element zu analysieren, müssen Sie das Element übergeben in // Daten kapern: Observer implementieren this.observe(this.$data); // Um Daten zu kapern, müssen Sie die Daten übergeben} kompilieren() {} beobachten() {} } 2.2.2 SeiteninitialisierungIn diesem Schritt müssen wir die Seite initialisieren, das heißt, die V-Text- und V-Model-Anweisungen analysieren und die Daten in Daten auf der Seite rendern. Der Schlüssel zu diesem Schritt besteht darin, die Kompilierungsmethode zu implementieren. Wie also wird das el-Element analysiert? Die Idee ist folgende:
Der Code lautet wie folgt: (sehen Sie sich hauptsächlich den Kompilierungsteil an) Klasse Vue { // Empfange das übergebene Objekt Konstruktor(Optionen) { // Nützliche Informationen erhalten this.$el = document.querySelector(options.el); dies.$data = Optionen.data; // Container: {attribute1: [wathcer1, wathcer2...], attribute2: [...]} dies.$watcher = {}; // 2. Elemente analysieren: Implementieren von Compile this.compile(this.$el); // Um das Element zu parsen, musst du das Element übergeben in // 3. Daten kapern: Observer implementieren this.observe(this.$data); // Um Daten zu kapern, müssen Sie die Daten übergeben} kompilieren(el) { // Analysieren Sie jeden untergeordneten Knoten unter dem Element, um el.children zu erhalten. // Hinweis: children gibt einen Elementsatz zurück, childNodes gibt einen Knotensatz zurück let nodes = el.children; // Analysiere die Anweisungen für jeden untergeordneten Knoten for (var i = 0, length = nodes.length; i < length; i++) { sei Knoten = Knoten[i]; // Wenn der aktuelle Knoten untergeordnete Elemente hat, den Knoten rekursiv analysieren if(node.children){ dies.kompilieren(Knoten); } // Elemente mit der v-text-Direktive analysieren if (node.hasAttribute("v-text")) { let attrVal = node.getAttribute("v-text"); node.textContent = this.$data[attrVal]; // Seite rendern} // Elemente mit v-model-Direktiven analysieren if (node.hasAttribute("v-model")) { let attrVal = node.getAttribute("v-Modell"); Knoten.Wert = dies.$data[attrVal]; } } } beobachten(Daten) {} } Auf diese Weise haben wir die Initialisierung der Seite erreicht. 2.2.3 Ansichten beeinflussen DatenDa die Eingabe über eine V-Modell-Anweisung verfügt, müssen wir eine solche Funktion implementieren: Wenn Zeichen in das Eingabefeld eingegeben werden, ändern sich die in den Daten gebundenen Daten entsprechend. Wir können ein Eingabeereignis an das Eingabeelement binden. Die Auswirkung des Ereignisses besteht darin, die entsprechenden Daten in Daten in den Wert in Eingabe zu ändern. Der Implementierungscode dieses Teils ist relativ einfach. Sie können ihn verstehen, indem Sie sich die markierte Stelle ansehen. Der Code lautet wie folgt: Klasse Vue { Konstruktor(Optionen) { dies.$el = document.querySelector(options.el); dies.$data = Optionen.data; dies.$watcher = {}; dies.kompilieren(dies.$el); dies.beobachten(diese.$daten); } kompilieren(el) { lass Knoten = el.children; für (var i = 0, Länge = Knoten.Länge; i < Länge; i++) { sei Knoten = Knoten[i]; wenn(Knoten.Kinder){ dies.kompilieren(Knoten); } wenn (node.hasAttribute("v-text")) { let attrVal = node.getAttribute("v-text"); node.textContent = dies.$data[attrVal]; } wenn (node.hasAttribute("v-model")) { let attrVal = node.getAttribute("v-Modell"); Knoten.Wert = dies.$data[attrVal]; // Schau mal hier! ! Nur noch drei Codezeilen! ! node.addEventListener("Eingabe", (ev)=>{ dies.$data[attrVal] = ev.target.value; // Sie können versuchen, es hier auszuführen: console.log(this.$data), // Sie können sehen, dass sich jedes Mal, wenn Sie Text in das Eingabefeld eingeben, auch der Nachrichtenwert in den Daten ändert}) } } } beobachten(Daten) {} } 2.2.4 DatenauswirkungsansichtBisher haben wir erreicht, dass die Daten in den Daten automatisch aktualisiert werden, wenn wir Zeichen in das Eingabefeld eingeben. Die Hauptaufgabe dieses Abschnitts besteht darin, dass bei einer Aktualisierung der Daten die an die Daten gebundenen Elemente automatisch die Ansicht auf der Seite aktualisieren. Die konkreten Vorstellungen sind wie folgt: 1) Wir implementieren eine Watcher-Klasse, die über eine Update-Methode zum Aktualisieren der Seite verfügt. Der Beobachtercode lautet wie folgt: Klasse Watcher{ Konstruktor(Knoten, aktualisiertesAttr, vm, Ausdruck){ //Speichere die übergebenen Werte. Diese Werte werden beim Rendern der Seite verwendet. this.node = node; dies.updatedAttr = updatedAttr; dies.vm = vm; dieser.Ausdruck = Ausdruck; dies.update(); } aktualisieren(){ dieser.Knoten[dieses.updatedAttr] = diese.vm.$data[dieser.Ausdruck]; } } 2) Überlegen Sie, welchen Daten wir Beobachter hinzufügen sollten? Wann sollten den Daten Beobachter hinzugefügt werden? Beim Parsen des Elements, wenn die Anweisungen für V-Text und V-Modell analysiert werden, bedeutet dies, dass dieses Element in beide Richtungen an die Daten gebunden werden muss. Daher fügen wir dem Container zu diesem Zeitpunkt einen Beobachter hinzu. Wir müssen eine Datenstruktur wie diese verwenden: {Attribut 1: [wathcer1, wathcer2...], Attribut 2: [...]}. Wenn das nicht ganz klar ist, können Sie die folgende Abbildung sehen: Sie können sehen, dass in der Vue-Instanz ein $watcher-Objekt vorhanden ist. Jedes Attribut von $watcher entspricht den Daten, die gebunden werden müssen, und der Wert ist ein Array, in dem die Beobachter gespeichert werden, die die Daten beobachtet haben. (Hinweis: Der Vue-Quellcode erstellt speziell eine Klasse namens Dep, die dem hier erwähnten Array entspricht. Dieser Artikel ist eine vereinfachte Version, daher werde ich ihn nicht im Detail vorstellen.) 3) Daten kapern: Verwenden Sie den Getter und Setter der Accessor-Eigenschaft des Objekts, um eine Aktion auszulösen, wenn die Daten aktualisiert werden. Der Hauptzweck dieser Aktion besteht darin, allen Beobachtern, die die Daten beobachtet haben, die Ausführung der Aktualisierungsmethode zu ermöglichen. Um zusammenzufassen, was wir in diesem Abschnitt tun müssen:
Der vollständige Code lautet wie folgt: Klasse Vue { // Empfange das übergebene Objekt Konstruktor(Optionen) { // Nützliche Informationen erhalten this.$el = document.querySelector(options.el); dies.$data = Optionen.data; // Container: {attribute1: [wathcer1, wathcer2...], attribute2: [...]} dies.$watcher = {}; // Elemente analysieren: Implementieren von Compile this.compile(this.$el); // Um das Element zu analysieren, müssen Sie das Element übergeben in // Daten kapern: Observer implementieren this.observe(this.$data); // Um Daten zu kapern, müssen Sie die Daten übergeben} kompilieren(el) { // Analysieren Sie jeden untergeordneten Knoten unter dem Element, um el.children zu erhalten. // Erweiterung: children gibt einen Elementsatz zurück, childNodes gibt einen Knotensatz zurück let nodes = el.children; // Analysiere die Anweisungen für jeden untergeordneten Knoten for (var i = 0, length = nodes.length; i < length; i++) { sei Knoten = Knoten[i]; // Wenn der aktuelle Knoten untergeordnete Elemente hat, den Knoten rekursiv analysieren, if (node.children) { dies.kompilieren(Knoten); } wenn (node.hasAttribute("v-text")) { let attrVal = node.getAttribute("v-text"); // node.textContent = this.$data[attrVal]; // Der Watcher ruft bei der Instanziierung „update“ auf und ersetzt diese Codezeile/** * Stellen Sie sich vor, welche Daten Wathcer zum Aktualisieren von Knotendaten verwenden muss? * egpinnerHTML = vm.$data[msg] * Die zu übergebenden Parameter sind also: aktueller Knoten, zu aktualisierende Knotenattribute, Vue-Instanz, gebundene Datenattribute*/ // Beobachter zum Container hinzufügen: {msg1: [Watcher, Watcher...], msg2: [...]} wenn (!this.$watcher[attrVal]) { dies.$watcher[attrVal] = []; } dies.$watcher[attrVal].push(neuer Watcher(Knoten, "innerHTML", dies, attrVal)) } wenn (node.hasAttribute("v-model")) { let attrVal = node.getAttribute("v-Modell"); Knoten.Wert = dies.$data[attrVal]; node.addEventListener("Eingabe", (ev) => { dies.$data[attrVal] = ev.target.value; }) wenn (!this.$watcher[attrVal]) { dies.$watcher[attrVal] = []; } // Anders als das oben verwendete innerHTML verwendet die Eingabe hier das Wertattribut this.$watcher[attrVal].push(new Watcher(node, "value", this, attrVal)) } } } beobachten(Daten) { Objekt.Schlüssel(Daten).fürJeden((Schlüssel) => { let val = data[key]; // Dieser Wert wird immer im Speicher gespeichert. Jedes Mal, wenn Sie auf data[key] zugreifen, greifen Sie auf diesen Wert zu Object.defineProperty(Daten, Schlüssel, { erhalten() { return val; // Du kannst data[key] hier nicht direkt zurückgeben, sonst gerät es in eine Endlosschleife}, setze(neuerWert) { wenn (Wert !== neuerWert) { val = newVal; // Ebenso kann data[key] hier nicht direkt gesetzt werden, was zu einer Endlosschleife führen würde this.$watcher[key].forEach((w) => { w.update(); }) } } }) }) } } Klasse Watcher { Konstruktor(Knoten, aktualisiertesAttr, vm, Ausdruck) { //Den übergebenen Wert speichern this.node = node; dies.updatedAttr = updatedAttr; dies.vm = vm; dieser.Ausdruck = Ausdruck; dies.update(); } aktualisieren() { dieser.Knoten[dieses.updatedAttr] = diese.vm.$data[dieser.Ausdruck]; } } lass vm = neues Vue({ el: "#app", Daten: { Nachricht: "Hallo Welt", msg2: „hallo xiaofei“ } }) An diesem Punkt ist der Code vollständig. 3. ZukunftspläneVerwenden Sie das Wissen über Entwurfsmuster, um die Probleme im obigen Quellcode zu analysieren und ihn mit dem Vue-Quellcode zu vergleichen. Dies gilt als Analyse des Vue-Quellcodes. Oben finden Sie den detaillierten Inhalt der Implementierungsmethode der bidirektionalen Vue-Datenbindung. Weitere Informationen zur bidirektionalen Vue-Datenbindung finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung des Selinux-Grundkonfigurationstutorials unter Linux
>>: Beispiel zum Erstellen eines lokalen Benutzers in MySQL und Erteilen von Datenbankberechtigungen
MySQL Binlog ist ein sehr wichtiges Protokoll in ...
Ich erstelle derzeit Nginx, kann aber nicht über ...
In früheren Blogbeiträgen habe ich mich auf einige...
Überblick Dieser Artikel stellt die in Spieleclie...
Wir erfinden das Rad neu: Hier verwenden wir Neuv...
Um zu verhindern, dass nicht konforme Daten in di...
Dieser Artikel stellt Ihnen ein einfaches HTML-Ap...
1. Neue Funktionen MySQL 5.7 ist ein spannender M...
In diesem Artikel wird der spezifische Code von V...
Inhaltsverzeichnis 1. Docker installieren 2. Erst...
Inhaltsverzeichnis Array-Destrukturierungszuweisu...
Hintergrund Alle Server des Unternehmens sind gek...
CSS3 implementiert einen umdrehbaren Hover-Effekt...
Wenn Sie möchten, dass die gesamte Benutzeroberfl...
Die Wiederverwendung von Code in Vue liefert uns ...