SPA mit Vue.js, vuetify, Laravel Lumen und Passport IV

Teil 4: Material Design Komponenten im Frontend durch Integration von vuetify

Albrecht Mauersberger
6 min readApr 10, 2019

Nachdem wir uns in Teil 3 eine Vue-App aufgesetzt und die API angebunden haben, wollen wir uns in diesem Teil daran machen, Material Design Komponenten via vuetify zur Verfügung zu stellen. Ich habe mich bewusst gegen Bootstrap entschieden, um ein gefühlt deutlich größeres Komponenten-Set zu erhalten, welches sich optimal in die Vue-Anwendung integrieren lässt, da es speziell für dieses Framework entwickelt wurde.

Einbindung von vuetify

Im ersten Schritt integrieren wir vuetify in unsere Anwendung, indem wir die benötigte Abhängigkeit via npm auflösen.

npm install --save vuetify

Im Ordner public\src\js erstellen wir uns eine vuetify.js und initialisieren hier vuetify

import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/app.styl'
import de from 'vuetify/es5/locale/de'

Vue.use(Vuetify, {
lang: {
locales: { de },
current: 'de'
},
})

Wir importieren hier erst Vue, danach vuetify A La Carte, damit nur diejenigen Module von vuetify im webpack build untergebracht werden, die benötigt sind und nicht alle Pakete. Danach integrieren wir die benötigten Styles und die deutsche Internationalisierung. Danach müssen wir diese Datei nur noch in der app.js nach dem Import von vue selber importieren.

import './vuetify'

Um die neuen Resourcen via webpack zu bundlen, werden noch ein paar Anpassungen benötigt, die später erklärt werden. Zunächst wollen wir aber noch Schriften und Icons hinterlegen.

Material Design Icons und Roboto Schrift integrieren

Für die Schriften und Icons sind wieder 2 npm-Abhängigkeiten notwendig:

  • roboto-typeface für die von vuetify genutzte Roboto-Schriftart
  • @mdi/font für die Material Design Icons
npm install --save-dev @mdi/font roboto-typeface

Die beiden Pakete müssen wir nun noch in der app.js importieren und die Icons in der vuetify-Konfiguration in der Datei vuetify.js hinterlegen.

Webpack-Anpassungen

Für die lokale Entwicklung werden wir etliche Loader benötigen, die wir uns ebenfalls installieren

  • css-loader und file-loader werden später für die Material Design Icons und die Roboto Schrift benötigt
  • vue-style-loader wird ebenfalls für die Material Design Icons benötigt
  • style-loader und stylus-loader werden für die .styl-Dateien von vuetify benötigt
  • vuetify-loader wird benötigt, um die vuetify-Abhängigkeiten der Templates beim Kompilieren korrekt auflösen zu können, so müssen wir uns nicht selber darum kümmern
  • sass-loader wird benötigt, um vuetify-Styles in Vue-Komponenten überschreiben zu können
npm install --save-dev css-loader file-loader vue-style-loader style-loader stylus-loader vuetify-loader sass-loader

Nun müssen wir nur noch die webpack-Konfiguration erweitern, damit wir die eigentlichen vuetify-Komponenten in den Vue-Dateien einsetzen können und diese dann korrekt kompiliert werden. Wichtig dabei ist das benötigte VuetifyLoaderPlugin und der vuetify-loader für die .vue-Dateien.

Nutzung der vuetify-Komponenten

Jetzt sind wir endlich soweit, die vuetify Komponenten in den Templates zu nutzen. Wir beginnen damit, die Seite für Firmen und Produkten beispielhaft mit einem Header zu versehen, der auf das Kontaktformular linkt, welches wir später noch erstellen werden.

Wichtige Elemente sind zum einen die Grid-Elemente v-container, v-flex und v-layout , mit denen man sich in jedem Fall beschäftigen sollte und der v-btn Button, der auf das Kontaktformular zeigt. Außerdem ist zu erwähnen, dass wir von der Produktseite aus dem Kontaktformular so verlinken, dass wir die ID des Produktes mitgeben. Diese wird also später ein Formularelement vorbelegen.

Erweiterung der Startseite und Integration der Navigation

Nun gehen wir an die Startseite. Wir wollen eine Navigation erstellen, die schon alle Produkte und Firmen ausgibt und wir wollen die Produkte und Firmen darunter als Cards ausgeben. Dafür müssen wir den axios-Aufruf der Produkte aus der Home.vue in die App.vue umlagern, und die Produkte und Firmen dann als Properties an die Vue-Komponenten übergeben. Die App.vue sieht dann wie folgt aus:

Wie wir sehen, werden die Produkte und Firmen an die Komponenten übergeben. Die Zuweisung des :key beim router-view hat den Hintergrund, dass die Komponente auch dann neu geladen wird, wenn man innerhalb derselben Route verlinkt, also zum Beispiel vom Produkt mit der ID 1 zum Produkt mit der ID 2 wechselt. Danach passen wir die Home.vue an. Hier kann dann, wie bereits geschrieben, der axios-Aufruf entfernt werden.

Wichtig hierbei ist, dass die übergebenen Firmen im script -Teil mittels props übernommen werden (siehe Dokumentation zu den Eigenschaften) und dann an die Komponenten Products und Companies durchgereicht werden (ebenfalls siehe Dokumentation zu der Komponentenverschachtelung).

Erstellung der Komponenten hinter den Routen

Nun werden diese drei Komponenten noch benötigt, die wir im Ordner components, der parallel zum Ordner pages liegt, erstellen. Außerdem legen wir noch das Kontaktformular an. Hieraus resultiert folgende Ordnerstruktur:

...
public
|_ src
|_ components
|_ Companies.vue
|_ Navigation.vue
|_ Products.vue
|_ js
|_ app.js
|_ router.js
|_ vuetify.js
|_ pages
|_ Company.vue
|_ Contact.vue
|_ Home.vue
|_ Product.vue
|_ App.vue
|_ index.html
...
package-lock.json
package.json

Zuerst erstellen wir die Produkte und die Firmen, die wir später auch nochmal separat im Router adressieren können.

Wichtige vuetify-Elemente hier sind die Cards, die wir nutzen, um die einzelnen Elemente auszugeben und die Platzhalter-Bilder, die später mit Logos oder ähnlichem bestückt werden könnten.

Befüllung der Navigation

Als nächsten nehmen wir uns der Navigation an und geben bereits hier alle Firmen und Produkte mit aus:

Wichtig zu erwähnen sind die vuetify-Elemente Toolbar, Menü und Liste, die hier verschachtelt genutzt werden, um die Navigation darzustellen.

Erstellung des Kontaktformulars

Jetzt fehlt nur noch das Kontaktformular, in welchem ebenfalls alle Produkte ausgegeben werden. Zudem geben wir ein Feld für die E-Mail-Adresse und für eine Nachricht aus. Dazu gibt es einen Submit-Button, der das Übermitteln der Daten an die API auslöst.

Zum Kontaktformular ist etwas mehr zu erklären. Wir gehen dabei von oben nach unten:

  • Wir geben ein Alert mit einer Erfolgsmeldung aus, wenn das Senden erfolgreich war. Dafür verwenden wir v-show , welches wir an die VariableshowSuccess hängen (siehe Dokumentation). Das Element wird also nur gezeigt, wenn die zugehörige Variable auf true steht. Das gleiche gilt für den Fehler-Alert, welcher analog an showError hängt.
  • Das Formular, welches mit v-form beginnt, ruft beim Absenden die Funktion onSubmit auf, welche später erklärt wird.
  • Die beiden Inputs, v-text-field für E-Mail-Adresse und v-text-area für die Nachricht sind als Pflichtfeld deklariert und bekommen einen Regelsatz hinterlegt, auf den beim Verlassen des Inputs geprüft wird.
  • Beim Absenden wird dann nochmal das gesamte Formular validiert und dann an die API gepostet. Der Submit-Button bekommt noch einen Loading-Spinner (siehe loading in den API-Props der Button-Dokumentation) , wenn isSending true ist.
  • Im data-Bereich des Script-Teils sieht man außerdem, dass das v-select für die Produkte aus der Route heraus belegt wird, indem der product -Parameter ausgewertet wird.

Erweiterung der router.js

Jetzt müssen wir die neuen Routen noch in die router.js eintragen und die damit verknüpften Komponenten importieren, damit alles erreichbar ist.

Wenn wir danach die Seiten für die Firmen, Produkte und das Kontaktformular aufrufen, erhalten wir in zum Beispiel folgende Ansichten:

  • Startseite/
  • Kontaktformular /contact

Aussicht

In diesem Teil des Tutorials haben wir mit vuetify alles etwas ansehnlicher gemacht und dabei etliche Elemente vorgestellt, insbesondere zum Erstellen einer Navigation und eines Formulars. Im nächsten Teil werden wir die Authentifizierung aus Teil 2 aufgreifen und ein Login-Formular erstellen, womit wir uns von der API einen access_token holen. In einem Adminbereich, der für eingeloggte Mitglieder sichtbar ist, wollen wir dann alle Kontaktanfragen ausgeben. Dabei werden wir Gebrauch von Vuex machen, was uns ein komfortables State Handling ermöglicht.

Vorherige Teile dieser Serie:

Weitere Teile dieser Serie:

--

--