Teaser - Vue.js + Nuxt.js = Dreamteam

Vue.js + Nuxt.js = Dreamteam

Willkommen zurück! Heute will ich euch zwei Frameworks vorstellen, die die Entwicklung von SEO-freundlichen Webanwendungen mit JavaScript extrem vereinfachen.

Beim Ersten handelt es sich um Vue.js (gesprochen wie das englische Wort view). Ich habe das erste Mal davon gehört, als die Version 2 frisch erschienen ist. Damals habe ich auch erste Versuche für eine eigene Anwendung unternommen, die jedoch aufgrund der noch ausbaufähigen Dokumentation gescheitert sind. Als ich im letzten Jahr dann auf Udemy aufmerksam geworden bin und dort viele Kurse über Vue.js angeboten werden, dachte ich mir, ich gebe dem Ganzen noch eine Chance. Und jetzt sitze ich hier und schreibe diesen Beitrag darüber. Ich habe mir insgesamt drei Kurse angeschaut, in jedem habe ich neue Sachen über das Framework gelernt. Ich habe mir auch Kurse zu Angular und React angeschaut und muss sagen, Vue.js gefällt mir eindeutig am besten. Es vereint aus technischer Sicht die Vorteile von beiden ohne die Nachteile zu übernehmen und der Start ist relativ einfach.

Vue.js als aufstrebenden Stern am Frameworkhimmel zu bezeichnen, wird dem Projekt mittlerweile gar nicht mehr gerecht. Auf GitHub hat es mittlerweile die meisten Sterne von den drei angesprochenen Frameworks. Ich habe auch eine sehr interessante Untersuchung zum Stand von JavaScript und den entsprechenden Frameworks gefunden. Das Ganze findet ihr hier. Die zwei auffälligsten Punkte für mich waren dabei:

  • Ungefähr ein Drittel der Entwickler, die schon mal Angular benutzt haben, würden es nicht mehr tun
  • Fast die Hälfte der befragten Entwickler, die schon mal von Vue gehört haben, möchten es lernen

Das zweite Framework setzt auf Vue.js auf und heißt Nuxt.js. Dieses Framework wurde ursprünglich entwickelt, da JavaScript Frontends ein paar grundsätzliche Probleme haben. Es wird eine fast leere index.html Datei vom Webserver geladen und anschließend die komplette Oberfläche über JavaScript erzeugt. Zum einen muss man dem Besucher einer Seite in dieser Zeit einen Ladebildschirm anzeigen, zum anderen sieht eine Suchmaschine, die die Seite besucht, initial keinen Inhalt. Das heißt, die Seite kann nicht vernünftig indiziert werden.

Vue.js bietet zur Lösung beider Probleme das serverseitige Erzeugen der Seite an, im Englischen auch server side rendering (kurz SSR) genannt. Weil das Ganze in Vue aber sehr kompliziert einzurichten ist, wurde Nuxt.js ins Leben gerufen. Es bietet alle Vorteile von SSR ohne irgendwas konfigurieren zu müssen. Auch andere Konzepte wie z.B. das Routing werden vereinfacht, was dieses Framework zur idealen Ergänzung von Vue.js macht.

Einführung in Vue.js

Schauen wir uns zunächst Vue.js genauer an. Um den Beitrag nicht zu sehr ausarten zu lassen, werde ich einige grundlegende Konzepte vorstellen und euch jeweils auf die entsprechende Dokumentation verweisen, damit ihr euch eingehender damit beschäftigen könnt. Ich will auch gleich darauf hinweisen, dass größere Projekte zwingend einen Bundler wie WebPack benötigen, auf den ich hier jedoch nicht eingehen will. Dieser ermöglicht die Strukturierung des Quellcodes in mehrere Dateien, die für die produktive Installation dann zu einer Datei zusammengefasst werden. Außerdem ermöglicht er in Verbindung mit Babel die Verwendung neuester JavaScript Funktionen, die dann je nach Zielbrowser entsprechend kompatibel gemacht werden.

Unsere erste “App”

Um mit der ersten Vue.js App beginnen zu können, legen wir zuerst einen Ordner an, ich nenne ihn vue-basics. Darin erstellen wir eine leere JavaScript Datei namens app.js und eine HTML Datei, die wir index.html nennen und die folgenden Inhalt aufweist:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue.js App</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"></div>
    <script src="app.js"></script>
</body>
</html>

Wie ihr seht, ist das überwiegend Standard Markup einer HTML5 konformen Webseite. Dazu kommen die beiden script Tags zum Einbinden von Vue.js und unserer eigenen JavaScript Datei, in der wir nun unsere erste Vue App erstellen werden. Um die App auf der Seite einhängen zu können, befindet sich im body noch ein div Element mit der ID app.

In die JavaScript Datei fügen wir nun folgenden Inhalt ein, der die minimale Logik für die Initialisierung unserer Vue.js App beinhaltet:

var app = new Vue({
    el: '#app'
})

Ihr könnt nun die index.html Datei über einen Doppelklick in eurem Standardbrowser öffnen. Für dieses einführende Beispiel brauchen wir nämlich keinen laufenden Webserver. Mit dem JavaScript Code, wird die App auf dem Element mit der ID app initialisiert.

Vue Dev Tools

Bevor wir nun mit der Programmlogik weiter machen, würde ich euch empfehlen, die Vue Dev Tools für euren Browser zu installieren. Damit wird die Überwachung des Programmzustands und die Fehlersuche extrem erleichtert. Falls ihr Chrome verwendet, müsst ihr für die Erweiterung in den Einstellungen noch den Zugriff auf die Datei URLs erlauben. Das ist notwendig, da wir die Datei per Doppelklick und damit mit dem file:// Protokoll geöffnet haben. Solltet ihr die index.html über einen Webserver öffnen, ist dieser Schritt nicht nötig.

Rechts oben im Browser sollte nun das Vue Logo erscheinen, das entsprechend gefärbt wird, wenn Vue.js auf einer Webseite erkannt wird. Wenn ihr nun die Entwicklerkonsole öffnet, findet ihr dort einen neuen Tab für die Dev Tools. Hier ein Bild, wie das Ganze im Chrome aussieht:

Entwicklerkonsole

In der oberen Leiste findet ihr auf der rechten Seite vier Icons zur Navigation. Damit könnt ihr zwischen den drei Bereichen Komponenten, Vuex und Events umschalten sowie die Anzeige aktualisieren. Wir werden uns in dieser Einführung überwiegend im ersten Bereichen Komponenten aufhalten.

Bei den Komponenten findet ihr nun unten auf der linken Seite den Strukturbaum eurer Komponenten, in unserem Fall bisher nur den Wurzelknoten <Root>. Auf der rechten Seite könnt ihr euch den Zustand und die Eigenschaften der einzelnen Komponenten anschauen, mehr dazu im nächsten Abschnitt.

Reaktivität

Unter Reaktivität versteht man das Verhalten, dass wenn sich der Zustand einer Komponente ändert, direkt auch die Anzeige in der Seite geändert wird. Von diesem Begriff leitet sich im Übrigen auch der Name des Frameworks React ab, das von Facebook entwickelt wird und von den Konzepten her sehr ähnlich zu Vue.js ist.

Um das Ganze in Aktion zu sehen, erweitern wir das div Element in unserem HTML Code um den Platzhalter {{ message }}:

<div id="app">
    {{ message }}
</div>

Um diesen Platzhalter mit der eigentlichen Nachricht zu füllen, erweitern wir den JavaScript Code wie folgt:

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hallo Welt mit Vue!'
    }
})

Wenn ihr nun die Seite im Browser aktualisiert, werdet ihr mit der entsprechenden Meldung begrüßt. Das Ganze ist nun auch bereits reaktiv. Um das zu testen, öffnet ihr den Konsolen Tab der Entwicklertools eures Browsers und gebt Folgendes ein:

app.message = "Tschüss Welt mit Vue";

Nun sollte sich die Meldung auf der Webseite entsprechend geändert haben. Wie ihr seht, kann man über die Variable app, die bei der Erstellung der Vue App zugewiesen wird, auf den Status der App zugreifen und diesen von außen beeinflussen. Ihr könnt nun im Übrigen auch in den Vue Dev Tools euer <Root> Element anklicken und seht dann auf der rechten Seite den Zustand dieser Komponente.

An dieser Stelle will ich die allgemeine Einführung auch schon beenden. Solltet ihr euch weiter mit den grundlegenden Funktionen von Vue beschäftigen wollen, gibt es dazu sehr viele Abschnitte in der Dokumentation. Für den Einstieg empfehle ich euch das Get Started Tutorial durchzuarbeiten. Dabei lernt ihr, wie Listen aus Arrays erstellt werden können, die bedingte Anzeige von Elementen funktioniert und die Eingaben von Benutzern in euren Komponenten verarbeitet werden können.

Komponenten

Komponenten ist dabei das richtige Stichwort. Jede Vue.js App besteht aus unzähligen Komponenten. Jede Komponente sollte dabei so einfach wie möglich aufgebaut sein und für genau eine Aufgabe zuständig sein. Für diese Einführung will ich eine Komponente erstellen, die eine einfache ungeordnete Liste anzeigt.

Zum Anlegen dieser Komponente, fügt ihr folgenden Quellcode am Anfang der JavaScript Datei ein:

Vue.component('nd-list', {
    data() {
        return {
            items: [
                'Apfel',
                'Birne',
                'Orange'
            ]
        }
    },
    template: `<ul>
                 <li v-for="item in items">{{ item }}</li>
               </ul>`
})

Damit wird eine Komponente namens nd-list global für die App registriert. Anders als bei der Root Komponente, wird data im Fall von allen weiteren Komponenten als Funktion umgesetzt. Das ist nötig, da es mehr als ein zugehöriges Element dieser Komponente geben kann. Würde data als Objekt umgesetzt sein, würden sich alle Elemente den gleichen Zustand teilen. Habt ihr also zwei Listen über diese Komponente erstellt und ihr ändert den Apfel in einer Liste zur Zitrone, würde auch die andere Liste geändert werden. Über die gezeigte data() Funktion, wird bei jeder Erstellung einer neuen Liste ein eindeutiges Objekt zurückgeliefert. Damit können die Zustände unabhängig voneinander verwaltet werden.

Da die registrierte Komponente initial an kein HTML Element gebunden ist, braucht sie selbst ein Template. In diesem Fall die gewünschte ungeordnete Liste. Darin wird eine sog. Direktive namens v-for verwendet, um aus den Elementen des Arrays eine entsprechende Liste zu erzeugen. Das Template einer Komponente muss übrigens immer ein eindeutiges Root Element haben, in unserem Fall <ul>. Es dürfen also z.B. keine zwei div Elemente auf oberster Ebene verwendet werden.

Im HTML Code kann die registrierte Komponente nun als benutzerdefiniertes HTML Tag wie folgt verwendet werden:

<div id="app">
    <nd-list></nd-list>
</div>

Wenn ihr die Seite aktualisiert, seht ihr die Obstliste, die ihr wiederum über die Vue Dev Tools in den Entwicklertools eures Browsers untersuchen könnt. Ihr könnt dort übrigens auch den Zustand (also die Liste des Obstes) verändern und sehen, wie sich das auf die Liste in der Anzeige auswirkt.

Auch zum Thema Komponenten könnte man stundenlang schreiben. Ich möchte hier aber wieder auf die sehr gute Dokumentation dazu auf der Homepage des Projekts verweisen.

Routing

Oft werden Anwendungen, die mit einem Framework wie Vue.js oder React umgesetzt werden, als sog. Single Page Application (kurz SPA) entwickelt. Das heißt, es wird vom Webserver immer die index.html Datei geliefert, den Rest erledigt das jeweilige Framework. Um nun trotz dieser einen Datei unterschiedliche Inhalte auf der Webseite anzuzeigen, wird Routing benötigt.

Für diesen Abschnitt reicht das Öffnen der index.html per Doppelklick nicht mehr aus. Wir brauchen dazu einen Webserver. Wer meinen Beitrag zu Node.js gelesen hat, der weis, dass das mit Node.js kein Problem ist. Ich werde für die folgenden Ausführungen daher auch auf einen minimalen Server setzen, der für unsere Zwecke ausreicht. Ihr müsst dazu natürlich Node.js installiert haben. Folgt dazu am besten der Beschreibung in meinem anderen Beitrag.

Das verwendete Paket heißt vue-http-server und basiert auf dem sehr beliebten http-server. Es erweitert diesen um eine entscheidende Funktion. Sollte eine Route und damit eine Datei nicht gefunden werden, kann man eine Fallback Datei angeben, die stattdessen geliefert werden soll.

Um das nötige Paket global zu installieren, führt ihr auf der Konsole eures Betriebssystems folgenden Befehl aus:

npm i -g vue-http-server

Nun wechselt ihr in dieser Konsole in den Ordner, in dem euer Projekt liegt und führt folgenden Aufruf aus, um den Server zu starten. Stellt zuvor sicher, dass Port 8080 auf eurem System nicht anderweitig belegt ist.

http-server -f index.html

Wenn ihr nun im Browser http://localhost:8080 aufruft, solltet ihr unser letztes Beispiel mit der Obstliste sehen.

Ich möchte an dieser Stelle nur sehr einfaches Routing zeigen, welches ihr auch in der Dokumentation von Vue findet. Es gibt ein sehr beliebtes Paket namens Vue Router, welches quasi der Standard für Routing mit Vue ist. Dieser bietet natürlich wesentlich mehr Umfang und Konfigurationsmöglichkeiten als dieses Beispiel. Für unseren Zweck reicht es aber aus.

Löscht zunächst in der HTML Datei den Inhalt aus dem div mit der ID app. Nun ersetzt ihr den Inhalt der JavaScript Datei mit folgendem Code, auf den ich gleich näher eingehen werde:

const NotFound = { template: '<p>Seite nicht gefunden. <a href="/">Zurück zur Startseite</a></p>' }
const Home = { template: '<p>Startseite -> <a href="/about">Über uns</a></p>' }
const About = { template: '<p>Über uns -> <a href="/">Startseite</a></p>' }

const routes = {
  '/': Home,
  '/about': About
}

new Vue({
  el: '#app',
  data: {
    currentRoute: window.location.pathname
  },
  computed: {
    ViewComponent () {
      return routes[this.currentRoute] || NotFound
    }
  },
  render (h) { return h(this.ViewComponent) }
})

Mit den ersten drei Zeilen, werden zunächst sehr einfache Templates erstellt. Es gibt also eine Startseite, eine Über uns Seite und eine Fehlerseite, falls die Route nicht gefunden wird. Bevor dann die eigentliche App initialisiert wird, werden noch die vorhandenen Routen definiert.

Im Vergleich zu unseren ersten Beispielen, gibt es zwei neue Eigenschaften, die eine App haben kann. Das erste sind sog. Computed Properties. Sie sind sehr ähnlich zu den Eigenschaften in data. Der Unterschied besteht darin, dass Computed Properties von mehreren anderen Eigenschaften aus data abhängen können und die Anzeige immer aktualisiert wird, sobald sich eine der Abhängigkeiten verändert.

Die zweite Neuerung ist die render Funktion. Sie wird aufgerufen, wenn die App initialisiert wird. Ich möchte nicht zu sehr auf die Implementierungsdetails eingehen, aber im Wesentlichen gibt sie den initialen Inhalt für das div mit der ID app zurück.

Wer nun ein bisschen mit der Anwendung spielt und auch mal verschiedene Routen testet, die nicht existieren, wird schnell merken, dass jeder Aufruf ein neuer Request an unseren Server ist. Normalerweise will man das vermeiden und sollte das Ganze dazu mit der History API des Browsers kombinieren.

Hier ein Ausschnitt, um unser bisheriges Beispiel darauf umzubauen:

const NotFound = { 
    template: `<p>
                 Seite nicht gefunden. 
                 <a href="javascript:;" onclick="app.goto('/', 'Startseite')">
                   Zurück zur Startseite
                 </a>
               </p>` 
}
const Home = { 
    template: `<p>
                 Startseite -> 
                 <a href="javascript:;" onclick="app.goto('/about', 'Über uns')">
                   Über uns
                 </a>
               </p>`
}
const About = { 
    template: `<p>
                 Über uns -> 
                 <a href="javascript:;" onclick="app.goto('/', 'Startseite')">
                   Startseite
                 </a>
               </p>`
}

// ...

var app = new Vue({
  // ...
  methods: {
    goto(path, title) {
        this.currentRoute = path;
        history.pushState({}, title, path);
    }
  },
  // ...
})

Wenn ihr nun zwischen Startseite und Über uns wechselt, wird die URL getauscht, der Inhalt der Seite entsprechend geändert und all das, ohne einen Request abzuschicken. Dazu wird in der Methode goto sowohl die Eigenschaft unserer App für die Route als auch die URL Zeile des Browsers über die History API verändert.

States

Kommen wir zum letzten wichtigen Konzept, das man verstanden haben sollte, bevor man größere Projekte mit Vue.js umsetzt. Bei unseren bisherigen Beispielen war der Zustand (englisch State) einer Komponente direkt in dieser gespeichert. Der Zustand befindet sich dabei innerhalb des data Attributs.

Wenn ihr größere Projekte plant, wird es nicht ausbleiben, dass Komponenten ihren Status austauschen sollen. Dabei gibt es im Wesentlichen zwei Richtungen. Wenn übergeordnete Komponenten Teile ihres Zustands an untergeordnete weitergeben wollen, können sie dazu Attribute verwenden. Diese funktionieren wie ganz normale HTML Attribute und müssen von der untergeordneten Komponente in Empfang genommen werden. Gehen wir davon aus, wir wollen unserer Obstliste zusätzliche Informationen geben:

<nd-list item-number="10"></nd-list>

Standardmäßig wird das angegebene Attribut erstmal ignoriert, da unsere Komponente nicht weis, was sie damit anfangen soll. Werfen wir also einen Blick auf eine neue Eigenschaft, die unsere Komponente haben kann:

export default {
    name: 'nd-list',
    props: ['itemNumber'],
    data() {
        return {
            items: [
                'Apfel',
                'Birne',
                'Orange'
            ]
        }
    },
}

Die neue Eigenschaft heißt props. Ihr müsst alle Attribute, die ihr innerhalb einer Komponente verwenden wollt, explizit in einer Liste erlauben. Beachtet auch, dass sich die Schreibweise in diesem Fall von der Definition im HTML Tag unterscheidet. Vue wandelt die Bindestriche dabei automatisch in Camel Case um, damit ihr einfacher innerhalb des JavaScript Codes damit arbeiten könnt. Ihr könnt nun auf den Wert des Attributes zugreifen, als wäre es innerhalb der data Eigenschaft:

<div>
    Die Liste beinhaltet {{ itemNumber }} Elemente.
    <ul>
        <li v-for="item in items">{{ item }}</li>
    </ul>
</div>

Natürlich hätte dieses Beispiel auch einfacher umgesetzt werden können, da ihr jederzeit die Länge eines Arrays ermitteln könnt. Ich hoffe es verdeutlicht euch trotzdem, wie ihr Daten nach unten in eurem Komponentenbaum weitergeben könnt.

Was ist nun, wenn wir Daten nach oben weitergeben wollen? Dazu gibt es das Eventsystem. Eine untergeordnete Komponente kann ein Event auslösen, worauf eine übergeordnete reagieren kann. Bleiben wir wieder bei unserer Obstliste und lösen ein Event aus, wenn ein Benutzer auf ein Element der Liste klickt:

<li v-for="item in items" @click="triggerEvent">{{ item }}</li>
export default {
    name: 'nd-list',
    props: ['itemNumber'],
    data() {
        // ...
    },
    methods: {
        triggerEvent: function(event) {
            this.$emit('clickEvent');
        }
    }
}

Dort wo die Liste verwendet wird, können wir das Event wie folgt verwenden:

<nd-list @click-event="doSomething"></nd-list>

Auch hier wandelt Vue die Schreibweise wieder automatisch zwischen Bindestrich und Camel Case um.

Super, ich weis jetzt, wie ich in beide Richtungen Daten austauschen kann. Bin ich damit bereit für größere Aufgaben?

-- ein vorschneller Entwickler

Theoretisch ja, aber ich will vorher auf ein Problem hinweisen, das mit der gezeigten Vorgehensweise einhergeht. Stellt euch vor, ihr habt einen Komponentenbaum mit mehreren Komponenten, die verschiedene Verzweigungen nach unten haben.

Entwicklerkonsole

Wollt ihr in diesem Beispiel zwischen den Komponenten 4 und 8 den Status austauschen, führt der Weg nur über 1. Dazu müsstet ihr eine Menge Events, Funktionen und Attribute definieren. Zum Glück gibt es andere Wege. Zwei möchte ich kurz nennen, um den Artikel nicht zu lang werden zu lassen aber nicht im Detail beschreiben.

  • Event Bus: Für mittelgroße Projekte hervorragend geeignet, um größere Distanzen zwischen Komponenten zu überbrücken. Dabei wird eine globale Komponente registriert, auf der ihr eure Events auslösen und in anderen Komponenten dann darauf reagieren könnt.
  • Vuex: Zustand losgelöst von Komponenten. Definiert einen Zustand auf Anwendungsebene, auf den alle Komponenten zugreifen können. Benötigt einiges an Einarbeitung, aber ich verwende es persönlich für alle Projekte, da man nie weis, wie umfangreich eine Anwendung werden kann. Wenn man von Beginn an auf Vuex setzt, kann man die Architektur beliebig nach oben skalieren.
Single File Components

Ihr könnt euch sicher vorstellen, dass bei einem größeren Projekt, die Umsetzung über die oben gezeigten Codeausschnitte schnell unübersichtlich werden kann. Vue bietet sog. Single File Components (kurz SFC) an. Dabei wird der komplette Quellcode (HTML, CSS und JavaScript) einer Komponente in einer Datei mit der Endung .vue zusammengefasst. Da das Ganze aber nur in Verbindung mit einem Bundler funktioniert, können wir das nicht direkt testen. Ich möchte euch ein Beispiel zeigen, das unsere Obstliste von oben als SFC umsetzt:

<template>
    <ul>
        <li v-for="item in items">{{ item }}</li>
    </ul>
</template>
<script>
    export default {
        name: "nd-list",
        data() {
            return {
                items: [
                    'Apfel',
                    'Birne',
                    'Orange'
                ]
            }
        },
    }
</script>
<style scoped>
    /** some component only css styling */
</style>

Ihr müsst euch dabei alle drei Teile in einer Datei vorstellen. Leider konnte ich es wegen Hightlight.js, welches ich für Syntaxhighlighting verwende, nicht sinnvoll in einen Code Block zusammenfassen. Es gibt für mehrere Entwicklungsumgebungen aber Plugins, die mit dieser Syntax umgehen können und euch auch Highlighting und Auto-Vervollständigung anbieten.

Wie auch in der Einführung zu Komponenten gilt, innerhalb des <template> Tags dürft ihr nur ein Rootelement haben. Beachtet auch das Schlüsselwort scoped der Style Definition. Es sorgt dafür, dass alle Definitionen nur innerhalb dieser Komponente greifen. Im Hintergrund werden sie dazu einfach mit einem eindeutigen Prefix versehen. Ihr könnt euch das in den Entwicklerwerkzeugen eures Browsers genauer ansehen.

Einführung in Nuxt.js

Nun werfen wir einen kurzen Blick auf Nuxt.js. Wenn man ein neues Projekt damit erstellt, ist automatisch alles Wichtige konfiguriert. Nuxt gibt auch eine genau Ordnerstruktur vor, in die man seine Dateien einsortieren muss. Auch ein Bundler ist bereits integriert, der im Standard ohne Konfiguration auskommt. Ich möchte in den nächsten Zeilen aber weniger auf alle Feinheiten eingehen, sondern vielmehr die Konzepte, die wir bei Vue.js gesehen haben, auf Nuxt.js ummünzen.

Das Erste was es anzumerken gibt ist, dass Nuxt komplett auf SFC setzt. Alles was wir also in den folgenden Abschnitten machen, wird sich in .vue Dateien abspielen.

Damit ihr das Ganze nachverfolgen könnt, möchte ich euch kurz zeigen, wie ihr ein Projekt mit Nuxt.js erstellen könnt. Legt dazu einen Ordner eurer Wahl auf eurem Dateisystem an, ich nenne meinen nuxt-basic. Anschließend wechselt ihr auf der Kommandozeile in diesen Ordner und führt folgendes Kommando aus:

npx nuxt-create-app .

Es installiert die nötigen Node.js Pakete und führt euch anschließend durch einen Assistenten, mit dem ihr eure Projekt anpassen könnt. Für unseren Fall reicht es, die Vorgaben zu akzeptieren. npx ist seit NPM 5.2 automatisch installiert.

Ihr könnt das Projekt über folgendes Kommando starten:

npm run dev

Dadurch führt ihr einen Server im Entwicklungsmodus aus, der auf Änderungen an den Projektdateien reagiert und die Seite im Browser automatisch aktualisiert. Öffnet im Browser http://localhost:3000, um euer erstes Nuxt.js Projekt zu begutachten. Ihr erhaltet damit automatisch u.a. folgende Funktionen, ohne einen Finger zu krümmen:

  • WebPack Bundler
  • Serverseitiges Erzeugen und damit SEO
  • Automatisches Routing über Ordnerstruktur

Stürzt euch am besten in die Dokumentation von Nuxt, um mehr über dieses geniale Framework zu erfahren. Es gibt auch einen sehr guten Kurs zu Nuxt von Max Schwarzmüller auf Udemy. Im Folgenden möchte ich noch kurz auf ein paar Unterschiede in den Konzepten von Vue.js und Nuxt eingehen.

Routing

Während ihr bei Vue eure Routen über die Konfiguration festlegen müsst, erledigt Nuxt diese Aufgabe automatisch. Alle .vue Dateien, die ihr im Ordner pages anlegt, sind als Routen im Browser erreichbar. Auch Unterordner sind dabei möglich. Legt zum Test einfach eine Datei namens about.vue im genannten Ordner an, die folgenden Inhalt aufweist:

<template>
    <div>
        Meine erste eigene Seite mit Nuxt
    </div>
</template>

Wenn euer Entwicklungsserver noch läuft, dann solltet ihr in der Konsole sehen, dass das Projekt direkt neu erstellt wird und die neue Route damit bereits verfügbar ist. Ihr könnt das testen, indem ihr http://localhost:3000/about im Browser aufruft.

Einfacher geht es nicht, oder?

Die aufgerufene Seite sieht natürlich relativ leer aus. Oft benötigt man innerhalb eines Projekts ein Layout, das auf allen Seiten eines Projektes gleich ist. Zum Glück bietet Nuxt auch dafür eine Lösung, nämlich den layouts Ordner. Mehr dazu natürlich im entsprechenden Abschnitt der Dokumentation, die übrigens selbst mit Nuxt.js erstellt ist. Klickt einfach ein bisschen darin rum und staunt über die Geschwindigkeit.

States

Es geht langsam dem Ende dieses Beitrags zu. Ich habe in den Ausführungen zu Vue.js kurz das Thema Vuex erwähnt. Es erlaubt den Status weg von den Komponenten und hin zur Anwendung zu verschieben. Damit lassen sich beliebig große Projekte sinnvoll verwalten. Nuxt bietet auch dafür einen Ordner namens store, indem ihr eure Vuex Stores definieren könnt. Ich möchte euch nochmal ermutigen, euch dieses Thema anzuschauen und für alle eure Projekte zu verwenden. Wenn man es einmal verstanden hat, ist es wirklich oft die Lösung von Problemen. Nuxt hat dazu einen eigenen Abschnitt in der Dokumentation.

Ausblick

Ich freue mich bereits auf das aktuelle Jahr, beide Projekte haben umfassende Neuerungen angekündigt, was die Entwicklung noch mehr vereinfachen und beschleunigen wird. Der Plan für Vue.js sieht zumindest aktuell noch vor, dieses Jahr die Version 3 zu veröffentlichen. Es wird die erste Version, die komplett in TypeScript entwickelt ist. Außerdem wird es Verbesserungen der Ausführgeschwindigkeit und des reaktiven Verhaltens geben. Ich hoffe, das Team kann den strammen Zeitplan einhalten.

Für Nuxt.js ist auch Version 3 in Aussicht gestellt worden. Hier habe ich bisher jedoch keine genaueren Informationen gefunden, was geändert wird. Solltet ihr euch auf dem Laufenden halten wollen, empfehle ich euch beiden Projekten auf Twitter zu folgen, dort gibt es Neuigkeiten meist zuerst.

Ich hoffe, ich konnte euch die Entwicklung neuer Projekte mit diesen beiden Frameworks ein bisschen schmackhaft machen. Ich bin ein großer Fan geworden und die Ökosysteme beider Projekte sind stark am wachsen. Fast täglich lese ich von neuen Projekten, die damit umgesetzt werden.

Seid auf jeden Fall auch auf meinen nächsten Beitrag gespannt. Dort werde ich euch ein eigenes Projekt vorstellen, an dem ich einige Wochen gefeilt habe und das euch den Start in eure Projekte erleichtern wird. Mehr möchte ich aktuell noch nicht verraten.

Jetzt will ich euch aber nicht mehr länger aufhalten. Wir lesen uns im nächsten Beitrag!