Interaktiver Warenkorb mit Vue.Js
Ein Warenkorb gehört zu jedem Online-Shop. Leider sind diese aber oftmals statisch und es ist für den Kunden schwierig die Anzahl an Produkten zu ändern oder ein Produkt wieder aus dem Warenkorb zu löschen. Damit die berechneten Informationen wie z.B. Gesamtpreis stimmen, benötigt es bei PHP nach jeder Änderung im Warenkorb ein Neuladen der Seite. Mit Vue.js lässt sich dies zum Glück recht einfach angenehm interaktiv gestalten:
Vue.js
Vue.js ist ein modernes JavaScript-Framework, mit dem sich bestehende Anwendung einfach um interaktive Elemente ergänzt werden können. So muss nicht der komplette Webshop neu in JavaScript implementiert werden, sondern es es können einzelne Elemente durch Vue.js interaktiv gestaltet werden. Dies bringt enorme Vorteile für alle bestehenden Anwendung, da man so Schritt für Schritt "alte" reine HTML-Bausteine durch moderne, interaktive JavaScript-Bausteine austauschen kann. Das Lernen und Anwenden von Vue.js ist zum Glück vergleichsweise einfach, so dass man schnell ein Erfolgserlebnis hat.
Interaktiver Warenkorb
Hier der komplette Code für die obige Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Warenkorb</title> <!-- Vue.js --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> </head> <body> <div id="app" class="container" style="width: 500px; margin-top: 20px;"> <table class="table table-bordered"> <thead> <tr> <th>Produkt</th> <th>Anzahl</th> <th>Einzelpreis</th> <th>Gesamtpreis</th> <th></th> </tr> </thead> <tbody> <tr v-for="(item, index) in warenkorb"> <td>{{ item.name }}</td> <td><input type="number" min="0" step="1" class="form-control" v-model="item.menge"></td> <td class="text-right">{{ item.preis.toLocaleString('de-DE', {minimumFractionDigits: 2}) }}</td> <td class="text-right">{{ (item.menge * item.preis).toLocaleString('de-DE', {minimumFractionDigits: 2}) }}</td> <td><button @click="deleteItem(index)">Löschen</button></td> </tr> <tr> <th colspan="3">Gesamtpreis</th> <td class="text-right">{{ gesamtpreis.toLocaleString('de-DE',{minimumFractionDigits: 2}) }}</td> <td></td> </tr> </tbody> </table> </div> <script> var app = new Vue({ el: '#app', data: { warenkorb: [ {name: 'Glühbirnen', menge: 5, preis: 1.20}, {name: 'Steckdosen', menge: 1, preis: 4.99}, {name: 'Tannenbaum', menge: 3, preis: 49.99}, ] }, computed: { gesamtpreis: function() { return this.warenkorb.reduce((acc, curr) => acc + curr.menge*curr.preis, 0); } }, methods: { deleteItem(index) { this.warenkorb.splice(index, 1); } } }) </script> </body> </html> |
Zuerst wird Vue.js und Bootstrap eingebunden:
1 2 3 4 5 |
<!-- Vue.js --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> |
Hinweis: Hier wird die Development-Version von Vue eingebunden. Wie auf Vue - Get Started beschrieben empfiehlt sich für den Produktiveinsatz die entsprechende Produktiv-Version von Vue.js zu nutzen.
Anschließend kommt das HTML der Tabelle:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<div id="app" class="container" style="width: 500px; margin-top: 20px;"> <table class="table table-bordered"> <thead> <tr> <th>Produkt</th> <th>Anzahl</th> <th>Einzelpreis</th> <th>Gesamtpreis</th> <th></th> </tr> </thead> <tbody> <tr v-for="(item, index) in warenkorb"> <td>{{ item.name }}</td> <td><input type="number" min="0" step="1" class="form-control" v-model="item.menge"></td> <td class="text-right">{{ item.preis.toLocaleString('de-DE', {minimumFractionDigits: 2}) }}</td> <td class="text-right">{{ (item.menge * item.preis).toLocaleString('de-DE', {minimumFractionDigits: 2}) }}</td> <td><button @click="deleteItem(index)">Löschen</button></td> </tr> <tr> <th colspan="3">Gesamtpreis</th> <td class="text-right">{{ gesamtpreis.toLocaleString('de-DE',{minimumFractionDigits: 2}) }}</td> <td></td> </tr> </tbody> </table> </div> |
Der einzige Unterschied zu einer normalen HTML-Tabelle besteht im Attribut des tr-Elements: v-for="(item, index) in warenkorb"
Dies ist ein Vue.js Befehl zur Umsetzung von Schleifen. Hier werden alle Elemente des Warenkorbs durchlaufen und für jeden Eintrag eine entsprechende Zeile in der Tabelle erstellt. Auf einer Seite wie zum Beispiel oil profit lassen sich Informationen zu neuen Nutzern ausgeben oder zu durchgeführten Transaktionen.
Mittels {{ var_name }} werden die Variablen von Vue entsprechend ausgegeben.
Zum Abschluss noch der entsprechende JavaScript-Code, um den Warenkorb interaktiv zu gestalten:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<script> var app = new Vue({ el: '#app', data: { warenkorb: [ {name: 'Glühbirnen', menge: 5, preis: 1.20}, {name: 'Steckdosen', menge: 1, preis: 4.99}, {name: 'Tannenbaum', menge: 3, preis: 49.99}, ] }, computed: { gesamtpreis: function() { return this.warenkorb.reduce((acc, curr) => acc + curr.menge*curr.preis, 0); } }, methods: { deleteItem(index) { this.warenkorb.splice(index, 1); } } }) </script> |
Hier definieren wird unter data unsere Variablen, die wir in Vue.js nutzen wollen. Hier haben wir nur den befüllten Warenkorb. Um den Gesamtpreis zu berechnen, greifen wir auf computed zurück. Dort definieren wir den Eintrag gesamtpreis, der dynamisch aus dem Warenkorb berechnet wird. Dazu werden dort alle Einträge aufgerechnet.
Zum Abschluss brauchen wir noch eine Methode um Elemente aus dem Warenkorb zu löschen. Dazu haben wir unter methods die Funktion deleteItem(index) definiert, die einen Eintrag aus dem warenkorb-Array heraus löscht.
Das war es auch schon, schon werden die Preise im Warenkorb automatisch berechnet wenn sich die Anzahl ändert oder wir ein Element wieder aus dem Warenkorb entfernen.
Autor: Nils Reimers