Zum Inhalt springen

Tutorial: NUXT.JS Application zur Darstellung aller Star Wars Filme – Teil #2

NUXT.JS

Content Area

Categories

Tutorial: NUXT.JS Application zur Darstellung aller Star Wars Filme – Teil #2

Update vom 27.09.2019:

  • Kleine Text-Korrekturen
  • Linting und Prettier entfernt, da anfangs ggf. zu komplex
  • Deshalb auch dadurch unnötigen Teil zur Fehlerbehandlung entfernt

Rückblick

Im ersten Teil haben wir nicht wirklich viel geschafft und gar nichts eigenes geschrieben, aber wir haben wertvolle Grundlagen für die Arbeit mit Node.js, Vue.js, NUXT.JS und Git gelegt und einen ersten Einblick in ein NUXT.JS Projekt gewonnen.

Zuletzt haben wir unseren Status per Git konserviert – falls du jetzt erst in das Tutorial einsteigt, kannst du dir unter dem oben angegebenen Repository-Link den aktuellen Projektstand herunterladen und mit npm install installieren.

Das Projekt starten kannst du dann mit npm run dev und schon hast du den aktuellen Projektstand.

Erstellen von Branches mit Git

Da wir gleich erstmals Code ändern, sollten wir einen neuen Entwicklungs-Zweig in Git anlegen. Das sollten wir jedes Mal tun, wenn sich wesentliche Änderungen ergeben. Oder wenn du etwas testen möchtet.

Das hat für dich außerdem den Vorteil, dass du in meiner Github-Repo zum Tutorial jeden einzelnen Teil als eigenen Branch herunterladen, installieren und miteinander vergleichen kannst!

Mein Ziel ist es einen neuen Entwicklungszweig mit dem Namen „teil_2“ anzulegen und dann direkt hinein zu wechseln. Damit lassen wir die Daten aus dem ersten Teil (Branch „Master“) völlig unberührt und können sie nicht beschädigen, sondern jederzeit dazu zurückkehren.

Gib dazu folgenden Befehl in der Konsole ein:

$ git checkout -b teil_2

Mit diesem Befehl schlagen wir tatsächlich beide Fliegen mit einer Klappe – wir erstellen den neuen Branch und „checken ihn direkt aus“, sprich wir wechseln in den Branch mit dem Namen „teil_2“.

Wichtig: Als Branchnamen kannst du wiederum keine Sonderzeichen verwenden!

Blick auf den neu erstellten Branch mit „GitLens“ (Plugin) für VS Code

Die „./layouts/default.vue“

Die „Startdatei“, die das Aussehen der gesamten Vue-Anwendung bestimmt, findest du im Verzeichnis ./layouts. Die Datei heißt default.vue und sieht folgendermaßen aus:

<template>
  <div>
    <nuxt />
  </div>
</template>

<style>
html {
  font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 16px;
  word-spacing: 1px;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: border-box;
  margin: 0;
}

.button--green {
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #3b8070;
  color: #3b8070;
  text-decoration: none;
  padding: 10px 30px;
}

.button--green:hover {
  color: #fff;
  background-color: #3b8070;
}

.button--grey {
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #35495e;
  color: #35495e;
  text-decoration: none;
  padding: 10px 30px;
  margin-left: 15px;
}

.button--grey:hover {
  color: #fff;
  background-color: #35495e;
}
</style>
Datei ./layouts/default.vue

Erklärung: Jedes Vue.js Template wird mit <template></template> gekapselt. Darin darf es wiederum nur EIN Root-Element geben.

Wichtig: Nur EIN RootElement!

Ein Beispiel dafür wie es NICHT geht

<template>
  <div> <!-- ERSTES RootElement -->
    <nuxt />
  </div>
  <div> <!-- ZWEITES RootElement -->
    Test
  </div>
</template>

Innerhalb des <template>-Tags darf es also nur ein Element geben, alle anderen müssen als Child-Child Elements darunter geordnet sein. Würden wir das oben dargestellte Beispiel „legal“ umsetzen wollen, dann müssten wir darum ein Root-Element spannen.

Welches das ist, ist (Vue / Nuxt.js) egal.

Wie man es richtig macht – nur ein RootElement

Wir nutzen im folgenden Beispiel erst einmal ein unsemantisches <div></div>:

<template>
  <div> <!-- EIN RootElement -->
    <div> <!-- ERSTER RootSibling -->
      <nuxt />
    </div>
    <div> <!-- ZWEITER RootSibling-->
      Test
    </div>
  </div>
</template>

Ein Startertemplate für alle Seiten in der ./layouts/default.vue erstellen

Ziel #1: Wir wollen einen Footer einbauen, der am unteren Ende der Seite „fixed“ positioniert ist.

Lösch alles in der ./layouts/default.vue und ersetze es mit folgendem Code:

<template>
  <div>
    <nuxt />
    <Footer />
  </div>
</template>

Beim Speichern sollte sich eure Vorschau im Browser direkt aktualisieren, allerdings ändert sich an der Darstellung nichts. Warum?
<Footer/> ist für Vue/Nuxt ein völlig legales aber bislang bedeutungsloses Tag. Es wurde auch korrekt geschlossen.

Unser Ziel istes aber, <Footer /> als Platzhalter zu nutzen, statt dessen jedes Mal unser Footer-HTML aus einer eigenen Component gerendert wird.

Erstellen unserer ersten Component

Das können wir lösen, indem wir unsere erste Komponente („Component“) schreiben und den Platzhalter <Footer /> dadurch ersetzen.

Wir erstellen eine neue Datei mit dem Namen Footer.vue im Ordner ./components .

<template>
  <b-navbar type="dark" variant="dark" fixed="bottom">
    <b-navbar-nav class="ml-auto">
      <b-nav-item to="/impressum">
        Impressum
      </b-nav-item>
    </b-navbar-nav>
  </b-navbar>
</template>
Datei ./components/Footer.vue

Wer sich ein wenig mit Bootstrap auskennt, dem mag der Code annähernd bekannt vorkommen. Nicht umsonst, schließlich verwenden wir BootstrapVue. Die BootstrapVue Component, die wir verwenden heißt Navbar, sieh dazu in die Doku, falls du etwas anpassen möchtest.

Ich will dies an dieser Stelle gar nicht allzu sehr vertiefen, für uns zählen erst einmal Erfolgserlebnisse 😉

<b-nav-item></b-nav-item> und seine Parameter erkläre ich später.

Um die Komponente aber nun in ./layouts/default.vue auch verwenden zu können, müssen wir sie zunächst importieren und anschließend deklarieren, erst danach steht uns unser Platzhalter-Tag zur Verfügung und wird durch den Code in der Component ersetzt.

Klingt anfangs kompliziert, ist es aber nicht. Versprochen.

Öffne deine ./layouts/default.vue und ersetze oder ergänze den bestehenden Code:

<template>
  <div>
    <nuxt />
    <Footer />
  </div>
</template>

<script>
import Footer from '~/components/Footer'

export default {
  components: {
    Footer
  }
}
</script>
Datei ./layouts/default.vue

Was bedeutet das?

In Zeile 9 importieren wir die Datei als Namespace mittels ES6.

In den folgenden Zeilen folgt ein Vue-Grundkontrukt, das wir immer wieder verwenden werden. Wichtig für uns ist nur, dass wir Components, die wir in einer Datei verwenden möchten, auch als solche registrieren müssen.

Erst danach kann man sie unter dem registrierten Namen verwenden – siehe Zeile 4 in unserer Datei. Wir speichern und zittern – Fehler? NEIN!

Zeit (vorsichtig) zu feiern und uns das Ergebnis mal im Browser anzusehen:

NUXT-Component Footer
NUXT-Component „Footer.vue“

Großartig! Nicht nur die Komponente wird dargestellt, sondern auch der Link scheint zu funktionieren, obwohl wir ein to="/impressum" statt einem href="/impressum" verwendet und generell auch gar kein <a>-Tag gesetzt haben. Natürlich liegt dort noch keine Datei, die müssen wir erst noch anlegen.

Später. Und dann erkläre ich auch den Rest des Codes.

Erstellen der Navigations-Component

Damit die Vorgehensweise sackt, wiederholen wir das Ganze noch einmal mit einer Component für die Hauptnavigation.
Generell gilt:

  • Component-Code in ./components/Dateiname.vue anlegen
  • Component in der Datei in der sie eingebettet werden soll importieren
  • Component im Script-Bereich registrieren
  • Component im Template verwenden

Let´s go. Wir erstellen eine Navigation.vue in ./components/ .

<template>
  <b-navbar toggleable="md" type="dark" variant="dark" fixed="top">
    <b-navbar-brand to="/" class="d-flex align-items-center">
      <h1 class="h4">NUXT.JS – Star Wars Films</h1>
    </b-navbar-brand>

    <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>

    <b-collapse id="nav-collapse" is-nav>
      <b-navbar-nav class="ml-auto">
        <b-nav-item to="/">
          Home
        </b-nav-item>
        <b-nav-item to="/test">
          Test
        </b-nav-item>
      </b-navbar-nav>
    </b-collapse>
  </b-navbar>
</template>
Datei ./components/Navigation.vue

Bis auf den „Toggle“der ab einer bestimmten Größe (Bootstrap-Breakpoint „md“ in dem Fall) einen Burger-Button einblenden soll, soweit nichts neues. Wir haben wieder zwei Links drin – einen auf / – also die Rootdatei – einen weiteren auf /test . Die zweite Datei existiert natürlich noch nicht.

Wenn du Details zum BootstrapVue-Code erfahren möchtest, wirf noch mal einen Blick auf die BootstrapVue Navigations-Doku.

Wiederum müssen wir die Komponente in ./layouts/default.vue importieren und registrieren.

<template>
  <div>
    <Navigation />
    <nuxt />
    <Footer />
  </div>
</template>

<script>
import Navigation from '~/components/Navigation'
import Footer from '~/components/Footer'

export default {
  components: {
    Navigation,
    Footer
  }
}
</script>
Datei ./layouts/default.vue

Wiederum erscheint beim Speichern kein Fehler, also zum Test im Browser èt Voilá!

default.vue mit Header und Footer-Navigation
default.vue mit Header und Footer-Navigation

Wenn du jetzt auf den „Test“ oder den „Impressum“-Link klickst erhältst du eine Fehlermeldung von Vue im Browser, der „Home“-Link bzw. der Klick auf den <b-navbar-brand>-Text funktioniert allerdings.

Doch woher weiß NUXT.js eigentlich, wo der Root-Link liegt und wie kann ich andere Seiten zuweisen?

Routing und die Pages bei NUXT.JS

Das ganze Geheimnis des Routing und der „Seiten“ versteckt sich bei NUXT.JS – anders als bei Vue.js! – im ./pages-Ordner.

Bei Vue kannst du die Struktur deiner Anwendung und wo die „Seiten“ liegen komplett individuell festlegen und musst dann aber in der Konfiguration auch manuell die Routen zuweisen.

NUXT.JS macht dies erheblich einfacher und das ist auch einer der wesentlichen Vorteile.

  1. „Seiten“ werden immer im ./pages-Ordner angelegt.
  2. Den dort abgelegten Seiten wird automatisch eine Route unter ihrem Dateinamen zugewiesen.

Für uns heißt das, dass wir eigentlich nur eine „impressum.vue“ und eine „test.vue“ im ./pages-Folder festlegen müssten und dann sollten auch die beiden in der Header- und Footernavigation definierten Links klappen.

Anlegen der „Test“-Seite inklusive automatischem Routing

Wir legen eine neue Seite an und speichern sie als ./pages/test.vue :

<template>
  <section class="container">
    <div>
      <h1 class="title">
        Test-Seite
      </h1>
      <h2 class="subtitle">
        Nur ein Test
      </h2>
    </div>
  </section>
</template>

<script></script>

<style></style>
Datei ./pages/test.vue

Wie ihr seht haben wir im Prinzip nur die ./pages/index.vue kopiert und ein paar Elemente entfernt. Was genau habe ich geändert?

  1. Da ich die Logo-Component nicht verwenden möchte, habe ich den Import und die Registration der Component aus dem <script>-Bereich entfernt.
  2. Ich habe die Logo-Component im Template gelöscht.
  3. Den <style>-Bereich habe ich komplett geleert. Ich bin nicht der Meinung, dass das in jede einzelne Datei gehört, sondern eher in ein globales Stylesheet. Das lösen wir aber später.

Warum lasse ich den <script> und den <style>-Bereich stehen, obwohl sie leer sind?

Da wir sie vermutlich noch einmal brauchen werden. Sind sie leer, werden sie ohnehin gar nicht erst transpiliert, stören uns also erst einmal nicht.

Anlegen der „Impressum“-Seite inklusive automatischem Routing

Das Gleiche machen wir nun mit der ./pages/impressum.vue :

<template>
  <section class="container">
    <div>
      <h1 class="title">
        Impressum-Seite
      </h1>
      <p>Den Text für das Impressum und die ganze Seite kannst du gerne selbst definieren.</p>
      <p>Nutz diese Seite gerne als Spielwiese um dich auszutoben!</p>
    </div>
  </section>
</template>

<script></script>

<style></style>
Datei ./pages/impressum.vue

Das to-Attribut in NUXT.JS

Wir werfen noch einmal einen Blick auf die ./components/Navigation.vue:

<b-nav-item to="/">
  Home
</b-nav-item>
Datei ./components/Navigation.vue

<b-nav-item> ist ein Element aus BootstrapVue, das das folgende Pendant aus Bootstrap4 in Vue ersetzt:

<li class="nav-item">
  <a class="nav-link" href="index.html">Home</a>
</li>
Ein Navigationselement in Bootstrap4

Dabei wird nicht nur das Listenelement selbst generiert, sondern auch der dazugehörige Link. Um den Link (bzw. die „Route“) zu setzen, müssen wir das to-Attribut verwenden und auf eine Datei in ./pages verlinken – dabei verzichten wir auf die Dateiendung .vue.

In Vue müssten wir diese Routen noch manuell eintragen, in NUXT.JS werden sie automatisch angelegt!

Styling der aktiven Seite und Seitenübergänge

Nur eine einzige Sache möchte ich gerne korrigieren, die mich rein visuell stört: Die „aktive“ Seite wird nämlich in der Navigation nicht hervorgehoben.

NUXT nutzt dazu eine eigene Klasse, also müssen wir diese nur richtig formatieren und fügen deshalb am Ende der ./layouts/default.vue folgendes hinzu:

<style>
.nuxt-link-exact-active {
  color: #41bb83 !important;
}
</style>
Am Ende der Datei ./layouts/default.vue

Jetzt wird auch der aktive Link immer in „Vue-Türkis“ angezeigt.

Und falls du es noch ein wenig „sexier“ haben möchtest, fügst du noch dies an der gleichen Stelle hinzu und hast elegante Transitions bei den Seitenwechseln:

<style>
.nuxt-link-exact-active {
  color: #41bb83 !important;
}

.page-enter-active,
.page-leave-active {
  transition: opacity 0.5s;
}

.page-enter,
.page-leave-to {
  opacity: 0;
}
</style>
Am Ende der Datei ./layouts/default.vue
Das Ergebnis des zweiten Teils der Übung "ERSTELLEN EINER NUXT.JS APPLICATION ZUR DARSTELLUNG ALLER STAR WARS FILME"
Das Ergebnis des zweiten Teils der Übung „ERSTELLEN EINER NUXT.JS APPLICATION ZUR DARSTELLUNG ALLER STAR WARS FILME“

Mein Tipp: „Perfektion durch Repetition“

– oder anders gesagt: Je öfter du eine Übung wiederholst, desto intuitiver kannst du das Gelernte später anwenden.

Ich würde dir also empfehlen, die default.vue noch mit weiteren (für uns später unnötigen) Elementen zu spicken, wie z.B. einem Jumbotron. Dabei lernst du auch noch ein wenig BootstrapVue.

Denk daran: Stage/Committe einfach per Git, dann kannst du jederzeit zum aktuellen Stand zurückkehren. Für uns ist es erst einmal nicht notwendig, dafür jedes mal einen eigenen Branch aufzumachen.

Hausaufgabe

  • Speichere den aktuellen Stand als Git-Commit.
  • Spiel ein wenig mit den Möglichkeiten von Nuxt und BootstrapVue herum.
  • Passe den Footer und die Hauptnavigation gerne auf deine persönlichen Anforderungen an.
  • Finde heraus, was das <nuxt /> Element macht und woher es seinen Content bezieht.

Vorschau

In Kapitel #3 beschäftigen wir uns damit SCSS in den Templates verfügbar zu machen, die Bootstrap-Variablen zu überschreiben und die ganze Anwendung etwas mehr „Star Wars“-like aussehen zu lassen.

Wer sich ausschließlich mit der Struktur und Funktionalität von Vue.js und NUXT.JS beschäftigen möchte, kann dieses Kapitel direkt überspringen und das Ergebnis aus Teil #3 dann in Kapitel #4 herunterladen.

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

To top of Page