Migration von jQuery zu Vue.js.

Der Autor des Artikels, dessen Übersetzung wir heute veröffentlichen, glaubt, dass es immer noch viele Programmierer auf der Welt gibt, die sich an jQuery wenden, wenn sie eine einfache Webanwendung entwickeln müssen. Normalerweise geschieht dies, wenn eine bestimmte Seite mit einfachen interaktiven Funktionen ausgestattet werden muss, die Verwendung eines JavaScript-Frameworks hierfür jedoch als Overkill erscheint. Immerhin handelt es sich dabei um Kilobyte unnötigen Codes, Vorlagen, Tools zum Erstellen von Projekten, Tools zum Packen von Modulen ... Gleichzeitig ist das Herstellen einer Verbindung zu einer jQuery-Seite mithilfe einer CDN-Ressource so einfach wie das Schälen von Birnen.



In diesem Artikel wird erläutert, wie ein mit jQuery erstelltes Projekt in Vue.js übersetzt wird. Dieses Projekt wird in jQuery erstellt und anschließend mit Vue neu gestaltet. Der Autor des Materials möchte allen zeigen, dass die Verwendung von Vue selbst in relativ kleinen Projekten nicht unbedingt eine übermäßige Vergrößerung der Codegröße solcher Projekte und eine große zusätzliche Belastung für den Programmierer bedeutet. Im Gegensatz dazu können Sie mit fast der gleichen Größe des Hilfscodes wie bei der Verwendung von jQuery die Produktivität steigern und die Qualität der Anwendungen verbessern.

Projektübersicht


Wir werden ein einfaches elektronisches Konto entwickeln, das auf dieser Open-Source-Vorlage von Sparksuite basiert.

In solchen Fallstudien werden häufig alle Arten von Aufgabenlisten verwendet. Ich hoffe, dass eine Abkehr von dieser Tradition die Geschichte frischer und interessanter macht, und gleichzeitig wird unsere Aufgabe schwierig genug sein, die Vorteile der Verwendung von Vue für die Entwicklung kleiner Projekte zu demonstrieren. Das Handbuch ist so konzipiert, dass jeder ohne besondere Schwierigkeiten es reproduzieren und die vorgeschlagenen Arbeitsmethoden beherrschen kann.

Hier ist die Kontovorlage, mit der wir arbeiten möchten.


Elektronische Rechnung

Wir werden interaktive Funktionen hinzufügen, damit es möglich ist, ein Produkt, seine Menge und seinen Stückpreis auszuwählen. Bei Änderung der Werte werden die Gesamtkosten der Ware und der Gesamtbetrag des Dokuments neu berechnet. Außerdem fügen wir hier eine Schaltfläche hinzu, mit der Sie neue Leerzeilen in das Konto einfügen können.

Ich habe die Vorlage geändert, indem ich den HTML-Code der leeren Zeichenfolge in das folgende Formular konvertiert habe:

<tr class="item">  <td><input value="" /></td>  <td>$<input type="number" value="0" /></td>  <td><input type="number" value="1" /></td>  <td>$0.00</td> </tr> 

JQuery-Projektentwicklung


Schauen wir uns zunächst an, wie Sie unser Problem mit jQuery lösen können.

 $('table').on('mouseup keyup', 'input[type=number]', calculateTotals); 

Wir verbinden den Ereignis-Listener mit der Tabelle. Dieser Listener ruft die Funktion calculateTotals Gesamtbeträge auf, wenn sich die Werte ändern, die den Stückkosten des Produkts oder seiner Menge entsprechen:

 function calculateTotals()  { const subtotals = $('.item').map((idx, val)  => calculateSubtotal(val)).get(); const total = subtotals.reduce((a, v)  => a + Number(v), 0); $('.total td:eq(1)').text(formatAsCurrency(total)); } 

Die Funktion nimmt die Zeilen der Tabelle und geht sie durch, übergibt jede der Zeilen an die Funktion calculateSubtotal Zwischensumme und fasst die Ergebnisse zusammen. Das Ergebnis der Berechnung fällt in die konstante Konstante. Infolgedessen wird der Gesamtbetrag des Dokuments in das entsprechende Feld des Kontos eingesetzt.

 function calculateSubtotal(row) { const $row = $(row); const inputs = $row.find('input'); const subtotal = inputs[1].value * inputs[2].value; $row.find('td:last').text(formatAsCurrency(subtotal)); return subtotal; } 

In diesem Code verweisen wir auf alle in der Zeile vorhandenen <input> -Felder und multiplizieren dann die im zweiten und dritten Feld gespeicherten Werte, um den subtotal zu erhalten. Dann wird dieser Wert in die letzte Zelle der Zeile eingefügt. Wir formatieren diesen Wert mit der Funktion formatAsCurrency . Hier ist ihr Code:

 function formatAsCurrency(amount) { return `$${Number(amount).toFixed(2)}`; } 

Darüber hinaus haben wir eine kleine Hilfsfunktion, die wir verwenden, um das gleiche Erscheinungsbild der Felder mit den Beträgen für Waren und für den gesamten Beleg zu gewährleisten. Wir müssen nämlich das $ -Zeichen vor den Zahlen in diesen Feldern haben und dass es sich um Dezimalzahlen mit zwei Dezimalstellen handelt.

 $('.btn-add-row').on('click', () => { const $lastRow = $('.item:last'); const $newRow = $lastRow.clone(); $newRow.find('input').val(''); $newRow.find('td:last').text('$0.00'); $newRow.insertAfter($lastRow); $newRow.find('input:first').focus(); }); 

Und schließlich haben wir einen Ereignishandler zum Klicken auf die Schaltfläche Add row hinzufügen, mit dem dem Dokument eine neue Zeile hinzugefügt wird. Hier nehmen wir die letzte Zeile in der Tabelle mit den Produktdaten und machen eine Kopie davon. Gleichzeitig fügen wir Standarddaten in die Felder dieser neuen Zeile ein. Darüber hinaus können wir uns um die Benutzerfreundlichkeit kümmern und uns auf das erste Feld einer neuen Zeile konzentrieren, sodass der Benutzer unmittelbar nach dem Hinzufügen einer neuen Zeile mit der Eingabe von Daten in das erste Feld beginnen kann.

Hier ist ein funktionierendes Beispiel für ein Konto, dessen interaktive Funktionen mithilfe von jQuery-Tools implementiert werden.

Nachteile der jQuery-basierten Lösung


Fragen wir uns, was die Nachteile des oben genannten Ansatzes sind oder wie wir unser Projekt verbessern können.

Möglicherweise haben Sie von neuen Bibliotheken wie Vue und React gehört, die es ihnen ermöglichen sollen, eher deklarativ als imperativ zu arbeiten. Wenn Sie sich den obigen jQuery-Code ansehen, ist klar, dass er hauptsächlich als eine Reihe von Anweisungen gelesen wird, die die Manipulation des DOM beschreiben. Der Zweck jedes Abschnitts dieses Codes, dh die Antwort auf die Frage, was er tut, ist oft recht schwierig herauszufinden, wenn man sich ansieht, wie er es tut. Natürlich können Sie die Absichten der verwendeten Codefragmente klarer machen, indem Sie sie in Funktionen mit sorgfältig ausgewählten Namen aufteilen. Wenn Sie diesen Code jedoch für eine Weile verlassen und dann wieder darauf zurückgreifen, stellt sich heraus, dass Sie noch einige Anstrengungen unternehmen müssen, um ihn zu verstehen.

Ein weiteres Problem mit diesem Code besteht darin, dass der Status der Anwendung im DOM gespeichert ist. Informationen zu den Produkten, die der Benutzer bestellen möchte, sind nur als Teil des HTML-Markups in der Benutzeroberfläche vorhanden. Wenn wir nur Daten an einem Ort ausgeben müssen, scheint dieses Problem nicht so schwerwiegend zu sein. Sobald es jedoch erforderlich wird, diese Daten an mehreren Stellen der Anwendung anzuzeigen, stehen wir vor der Aufgabe, Daten zu synchronisieren. Ohne eine einzige Quelle zuverlässiger Daten, wie in unserem Fall, ist es sehr schwierig, diese während der gesamten Anwendung auf dem neuesten Stand zu halten.

Während der Verwendung von jQuery hindert uns nichts daran, den Status der Anwendung außerhalb des DOM zu speichern und das oben beschriebene Problem zu vermeiden. Bibliotheken wie Vue bieten Funktionen, mit denen Anwendungen mit einer guten Architektur erstellt werden können. Diese Bibliotheken helfen dem Programmierer, saubereren, strukturierteren Code zu schreiben.

Projektübersetzung auf Vue


Lassen Sie uns nun darüber sprechen, wie Sie dieselbe Funktionalität in Vue wiederherstellen können. Um die Funktionen von Vue zu nutzen, verbinden Sie diese Bibliothek einfach mit einer normalen Webseite, genau wie Sie es mit jQuery tun. Das heißt, Sie müssen das System nicht zum Packen von Modulen oder eines Transpilers verwenden. Sie müssen die Anwendung nicht in Komponenten aufteilen und ihren Code in .vue-Dateien zerlegen.

Wir beginnen mit der Übersetzung des Projekts in Vue, indem wir den Inhalt des <script> ersetzen:

 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> 

Der nächste Schritt besteht darin, eine neue Instanz von Vue zu erstellen:

 const app = new Vue({ el: 'table' }); 

Der einzige Parameter, der an den Konstruktor der neuen Vue-Instanz übergeben wird, ist el . Dies ist ein Selektor (der gleiche wie in jQuery), der den Teil des Dokuments identifiziert, den wir mit Vue steuern möchten.

Vue können Aufgaben unterschiedlicher Größe zugewiesen werden - von der Verwaltung einer ganzen Seite (z. B. einer einseitigen Anwendung) bis zu einem kleinen Fragment, das in einem <div> . In unserem Beispiel ist Vue für die Arbeit mit der HTML-Tabelle verantwortlich.

Daten


Fügen Sie der Vue-Instanz bedingte Daten für drei Zeilen des Dokuments hinzu:

 const app = new Vue({ el: 'table', data: {   items: [     { description: 'Website design', quantity: 1, price: 300 },     { description: 'Hosting (3 months)', quantity: 1, price: 75 },     { description: 'Domain name (1 year)', quantity: 1, price: 10 },   ] } }); 

In der data speichern wir den Status der Anwendung. Der Status enthält nicht nur die Daten, mit denen unsere Anwendung arbeiten soll, sondern auch Informationen zum Status der Benutzeroberfläche (z. B. welcher Abschnitt der Anwendung, der aus mehreren Registerkarten besteht, derzeit aktiv ist oder ob ein bestimmtes Widget minimiert ist). wie ein "Akkordeon" oder erweitert).

Vue hilft dabei, den Status der Anwendung von ihrer Darstellung (dh vom DOM) zu trennen und den Status zentral an einem Ort zu speichern, der eine einzige Quelle für zuverlässige Daten darstellt.

Vorlagenänderung


Konfigurieren Sie nun die Vorlage so, dass die im Datenobjekt gespeicherten data angezeigt werden. Da wir dem Framework mitgeteilt haben, dass wir mit einer Tabelle mithilfe einer Vue-Instanz arbeiten möchten, können wir die Vue-Vorlagensyntax im HTML-Code verwenden, der diese Tabelle beschreibt, um Vue mitzuteilen, wie die Tabelle gerendert und wie sie verwendet wird arbeiten.

Mit dem Attribut v-for können wir aus dem Elementarray einen HTML-Codeblock für jedes Element ableiten:

 <tr class="item" v-for="item in items"> </tr> 

Vue wiederholt dieses Markup für jedes Element des Arrays (oder Objekts), das an v-for . Dies ermöglicht es uns, auf jedes Element in der Schleife zu verweisen. In diesem Fall wird dieses Element durch die item . Da Vue die Eigenschaften des data überwacht, aktualisiert das Framework das Markup dynamisch, wenn sich der Inhalt des Elementarrays ändert. Alles, was wir tun müssen, ist den Status durch Hinzufügen oder Entfernen von Elementen zu ändern, und Vue aktualisiert automatisch die Benutzeroberfläche.

Zusätzlich müssen wir Eingabefelder hinzufügen, die der Benutzer ausfüllen kann, indem er eine Beschreibung des Produkts, des Stückpreises und der Menge eingibt:

 <td><input v-model="item.description" /></td> <td>$<input type="number" v-model="item.price" /></td> <td><input type="number" v-model="item.quantity" /></td> <td>${{ item.price * item.quantity }}</td> 

Hier verwenden wir das v-model Attribut, um die bidirektionale Datenbindung zwischen Eingabefeldern und Eigenschaften im Datenmodell zu konfigurieren. Dies bedeutet, dass das Ändern der Daten in den Eingabefeldern zu deren Änderung im Modell führt und umgekehrt.

In der letzten Zelle verwenden wir geschweifte Klammern {{}} , um Text anzuzeigen. Sie können jeden funktionierenden JavaScript-Ausdruck in Klammern verwenden. In diesem Fall multiplizieren wir die beiden Eigenschaften des Elements und geben aus, was passiert ist. Wieder überwacht Vue das Datenmodell. Wenn Sie eine Eigenschaft ändern, wird der Ausdruck automatisch wiedergegeben.

Ereignisse und Methoden


Jetzt haben wir eine Vorlage zur Anzeige der items und stehen vor der Frage, wie der Tabelle neue Zeilen hinzugefügt werden können. Da Vue alles, was sich im Elementarray befindet, auf der Seite ausgibt, reicht es aus, das Vue-Objekt mit allen Werten zu übergeben, die im Elementarray vorhanden sein sollten, um eine leere Zeichenfolge auf der Seite anzuzeigen.

Um eine Funktion zu erstellen, auf die über die Vorlage zugegriffen werden kann, müssen Sie diese Funktion als Eigenschaft des methods an die Vue-Instanz übergeben:

 const app = new Vue({ // ... methods: {   myMethod() {} }, // ... }) 

addRow Methode addRow , die aufgerufen werden kann, um addRow ein neues Element hinzuzufügen:

 methods: { addRow() {   this.items.push({ description: '', quantity: 1, price: 0 }); }, }, 

Bitte beachten Sie, dass alle von uns erstellten Methoden automatisch an die Vue-Instanz gebunden werden, sodass wir über diese Methoden auf die Eigenschaften des data und anderer Methoden als Eigenschaften zugreifen können.

Jetzt haben wir also eine Methode. Wie rufe ich es auf, indem ich auf die Schaltfläche Add row klicke? Um Steuerelementen in einer Vorlage Ereignis-Listener hinzuzufügen, verwendet Vue die Syntax v-on:event-name .

 <button class="btn-add-row" @click="addRow">Add row</button> 

Vue bietet auch eine Verknüpfung für das Konstrukt v-on :, das wie @ aussieht. Es wird im obigen Code-Snippet verwendet. Sie können eine beliebige Methode aus der Vue-Instanz als Ereignishandler verwenden.

Berechnete Eigenschaften


Jetzt müssen wir nur noch den Gesamtbetrag für das Dokument am Ende der Rechnung abheben. Dies kann in der Vorlage selbst erfolgen. Wie bereits erwähnt, können Sie mit Vue alle funktionierenden JS-Ausdrücke in Konstruktionen aus geschweiften Klammern platzieren. Es ist jedoch viel besser, sich an einen Ansatz zu halten, bei dem nur sehr einfache Logik und nichts mehr in der Vorlage gespeichert sind. Wenn die Logik von der Vorlage getrennt ist, ist der Code sauberer und einfacher zu testen.

Zu diesem Zweck können wir die übliche Methode verwenden, aber ich glaube, dass in diesem Fall die sogenannte berechnete Eigenschaft für uns am besten ist. Das Arbeiten mit solchen Eigenschaften ähnelt dem obigen Arbeiten mit Methoden. Um solche Eigenschaften zu erstellen, wird nämlich ein computed Objekt an die Vue- computed , das Funktionen enthält, deren Ausführungsergebnisse in der Vorlage verwendet werden sollen:

 const app = new Vue({ // ... computed: {   total() {     return this.items.reduce((acc, item) => acc + (item.price * item.quantity), 0);   } } }); 

Jetzt kann auf die berechnete Eigenschaft aus der Vorlage verwiesen werden:

 <tr class="total"> <td colspan="3"></td> <td>Total: ${{ total }}</td> 

Wie Sie vielleicht bemerkt haben, funktionieren die berechneten Eigenschaften in der Vorlage so, als wären sie Daten. In diesem Fall müssen Sie nichts in der Vorlage "aufrufen". Die Verwendung berechneter Eigenschaften hat einen weiteren Vorteil. Vue ist ein ziemlich intelligentes System, das die zurückgegebenen Werte zwischenspeichert und nur dann wiedergibt, wenn die Eigenschaften geändert werden, von denen die Werte der berechneten Eigenschaften abhängen.

Wenn wir die Methode zur Berechnung des Gesamtbetrags für das Dokument verwenden würden, würden die Berechnungen jedes Mal durchgeführt, wenn die Vorlage ausgegeben wurde. Da wir jedoch die berechnete Eigenschaft verwenden, wird der Gesamtbetrag nur neu berechnet, wenn die quantity oder price in den Zeilen der Tabelle geändert werden.

Filter


Möglicherweise haben Sie bemerkt, dass bei der Implementierung unseres mit Vue erstellten Projekts ein kleiner Fehler aufgetreten ist. Es besteht darin, dass, wenn die Preise einzelner Waren in ganzen Zahlen ausgedrückt werden, die berechneten Werte der Gesamtbeträge in Zeilen und des Gesamtbetrags im Dokument als ganze Dollarwerte ohne Cent angezeigt werden. Wir möchten, wie im jQuery-Beispiel, dass diese Zahlen immer zwei Dezimalstellen enthalten.

Anstatt den Code zu ändern, der für die Berechnung des Gesamtwerts der Zeile verantwortlich ist, und den Code, der den Gesamtbetrag für das Dokument berechnet, können wir die praktischen Datenformatierungsfunktionen von Vue nutzen. Es geht um Filter.

Wie Sie wahrscheinlich bereits verstanden haben, reicht es zum Erstellen eines Filters aus, ein Objekt (in diesem Fall filters ) mit dem entsprechenden Schlüssel an die Vue-Instanz zu übergeben:

 const app = new Vue({ // ... filters: {   currency(value) {     return value.toFixed(2);   } } }); 

Hier haben wir einen sehr einfachen Filter namens currency . Es ruft die Funktion toFixed(2) für den an sie übergebenen numerischen Wert auf und gibt das Ergebnis zurück. Sie können diesen Filter in der Vorlage wie folgt verwenden:

 <td>Total: ${{ total | currency }}</td> 

Hier ist die fertige Implementierung unseres Projekts auf Vue.

Zusammenfassung


Wenn Sie zwei Versionen des Projekts vergleichen, eine mit jQuery erstellte und die zweite mit Vue, werden Sie die folgenden Stärken der Vue-basierten Anwendung feststellen:

  • Eine klare Trennung zwischen der Benutzeroberfläche, der Logik und den Daten, die die Benutzeroberfläche steuern. Der Code ist klarer, es wird einfacher zu testen sein.
  • Eine deklarative Beschreibung der Schnittstelle. Der Programmierer muss sich nur darum kümmern, wie er beschreibt, was er auf dem Bildschirm sehen möchte, und nicht, wie er auf das DOM zugreift, um der Anwendungsseite das gewünschte Aussehen zu verleihen.

Die Bibliotheken Vue und jQuery sind fast gleich groß (in Kilobyte). Natürlich kann die Größe von jQuery durch die Verwendung unserer eigenen Bibliotheksassembly reduziert werden, aber selbst in relativ einfachen Projekten, wie beispielsweise unserem Beispiel eines elektronischen Kontos, glaube ich, dass die einfache Entwicklung und Lesbarkeit des Codes eine leichte Vergrößerung der Anwendung rechtfertigen.

Darüber hinaus sind die Funktionen von Vue viel umfassender als die hier beschriebenen. Die Stärke dieses Frameworks liegt in der Tatsache, dass Sie modulare, wiederverwendbare Benutzeroberflächenkomponenten erstellen können, aus denen Sie komplexe Clientanwendungen erstellen können.

Wenn Sie sich für das Thema der Entwicklung von Webanwendungen auf Vue interessieren, schauen Sie sich dieses Material an . Wenn Sie darüber nachdenken, Projekte von reinem JS nach Vue zu verlagern, finden Sie hier unsere jüngste Veröffentlichung zu diesem Thema.

Liebe Leser! Verwenden Sie jQuery? Und wenn Sie es verwenden, planen Sie, diese Bibliothek in etwas anderes zu ändern, zum Beispiel in Vue?

Source: https://habr.com/ru/post/de414073/


All Articles