Skip to content

3. Eine erste [nuxt.js]-Anwendung

3.1. Erstellen der Anwendung

Für unsere [nuxt.js]-Entwicklung werden wir weiterhin VS Code verwenden. Wir haben einen leeren [dvp]-Ordner erstellt, in dem wir unsere Beispiele ablegen werden. Dann öffnen wir diesen Ordner:

Image

Wir speichern den Arbeitsbereich unter dem Namen [intro-nuxtjs] [3-5]:

Image

Wir öffnen ein Terminal [6-7]:

Image

Bisher haben wir den JavaScript-Paketmanager [npm] verwendet. Zur Abwechslung nutzen wir hier den [yarn]-Manager. Wie [npm] ist er in aktuellen Versionen von [node.js] vorinstalliert. Um eine erste [nuxt]-Anwendung zu erstellen, verwenden wir den Befehl [yarn create nuxt-app <Ordner>] [1]. Der Befehl fragt einige Informationen zum zu erstellenden Projekt ab und generiert es, sobald diese Informationen eingegeben wurden [2]:

Image

In [2] wurde ein kompletter Dateibaum erstellt. Die Datei [package.json] listet die JavaScript-Bibliotheken auf, die in den Ordner [node-modules] heruntergeladen wurden [4]:


{
  "name": "nuxt-intro",
  "version": "1.0.0",
  "description": "nuxt-intro",
  "author": "serge-tahe",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
  },
  "dependencies": {
    "nuxt": "^2.0.0",
    "bootstrap-vue": "^2.0.0",
    "bootstrap": "^4.1.3",
    "@nuxtjs/axios": "^5.3.6"
  },
  "devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-prettier": "^3.0.1",
    "prettier": "^1.16.4"
  }
}

Diese Datei spiegelt die Antworten wider, die beim Befehl [create nuxt-app] zur Definition des erstellten Projekts gegeben wurden (November 2019). Der Leser verfügt möglicherweise über eine andere [package.json]-Datei:

  • er hat möglicherweise andere Antworten auf die Fragen gegeben;
  • der Befehl [create nuxt-app] hat sich seit der Erstellung dieses Dokuments möglicherweise weiterentwickelt: Abhängigkeiten und Versionen haben sich möglicherweise geändert;

Zeile 8 des Skripts ist der Befehl, der die Anwendung startet:

Image

  • In [4] sehen wir, dass die Anwendung unter der URL [localhost:3000] verfügbar ist;
  • in [5-6] sehen wir, dass die Anwendung einen Server [6] und einen Client (dieses Servers) [5] startet;

Rufen wir die URL [http://localhost:3000/] in einem Browser auf:

Image

3.2. Beschreibung der Verzeichnisstruktur einer [nuxt]-Anwendung

Sehen wir uns die Verzeichnisstruktur der erstellten Anwendung an:

Image

Die Ordner haben folgende Funktionen:

assets
unkompilierte Anwendungsressourcen (Bilder usw.);
static
Dateien in diesem Ordner sind im Stammverzeichnis der Anwendung verfügbar. Wir legen in diesem Ordner Dateien ab, die im Stammverzeichnis der Anwendung zu finden sein müssen, wie beispielsweise die für Suchmaschinen bestimmte Datei [robots.txt];
Komponenten
die [View]-Komponenten der Anwendung, die in [Layouts] und [Seiten] verwendet werden;
Layouts
die [Vue]-Komponenten der Anwendung, die zur Gestaltung der [Seiten] verwendet werden;
Seiten
die [Vue]-Komponenten, die von den verschiedenen Routen der Anwendung angezeigt werden. Diese könnten als Ansichten der Anwendung bezeichnet werden. Seiten spielen in [Nuxt] eine besondere Rolle: Routen werden dynamisch auf der Grundlage der Verzeichnisstruktur im Ordner [pages] erstellt;
Middleware
Skripte, die bei jeder Änderung einer Route ausgeführt werden. Sie ermöglichen es Ihnen, diese Routen zu steuern;
Plugins
hat einen irreführenden Namen. Er kann sowohl Plugins als auch Standardskripte enthalten. Die Skripte in diesem Ordner werden beim Start der Anwendung ausgeführt;
store
Wenn er ein Skript [index.js] enthält, definiert dieses Skript eine Instanz des [Vuex]-Stores;

Wenn ein Ordner leer ist, kann er aus der Verzeichnisstruktur entfernt werden. Oben können die Ordner [assets, static, middleware, plugins, store] entfernt werden [2].

3.3. Die Konfigurationsdatei [nuxt.config]

Die Ausführung der Anwendung wird durch die folgende Datei [nuxt.config.js] gesteuert:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: process.env.npm_package_description || ''
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: [],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Doc: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
}
  • Zeile 2: Der Typ der generierten Anwendung:
    • [universal]: Client/Server-Anwendung. Beim ersten Laden der Anwendung sowie bei jeder Seitenaktualisierung im Browser wird der Server aufgefordert, die Seite bereitzustellen;
    • [sap]: Typ [Single Page Application]: Ein Server liefert zunächst die gesamte Anwendung aus. Danach arbeitet der Client unabhängig, auch wenn eine Seite im Browser aktualisiert wird;
  • Zeilen 6–18: Definieren den HTML-Header `<head>` für die verschiedenen Seiten der Anwendung:
    • Zeile 7: das <title>-Tag für den Seitentitel;
    • Zeilen 8–16: die <meta>-Tags;
    • Zeile 17: die <link>-Tags

In der generierten Anwendung sieht das <head>-Tag wie folgt aus (Quellcode der im Browser angezeigten Seite):


<title>nuxt-intro</title>
<meta data-n-head="ssr" charset="utf-8">
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
<meta data-n-head="ssr" data-hid="description" name="description" content="nuxt-intro">
<link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="preload" href="/_nuxt/runtime.js" as="script">
<link rel="preload" href="/_nuxt/commons.app.js" as="script">
<link rel="preload" href="/_nuxt/vendors.app.js" as="script">
<link rel="preload" href="/_nuxt/app.js" as="script">

Nun ändern wir die Datei [nuxt.config] wie folgt:


head: {
    title: 'Introduction à [nuxt.js]',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: 'ssr routing loading asyncdata middleware plugins store'
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},

Wenn wir die Anwendung erneut ausführen, hat sich der <head>-Tag wie folgt geändert (Quellcode der im Browser angezeigten Seite):


  <head >
    <title>Introduction à [nuxt.js]</title>
    <meta data-n-head="ssr" charset="utf-8">
    <meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
    <meta data-n-head="ssr" data-hid="description" name="description" content="ssr routing loading asyncdata middleware plugins store">
    <link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
    <link rel="preload" href="/_nuxt/runtime.js" as="script">
    <link rel="preload" href="/_nuxt/commons.app.js" as="script">
    <link rel="preload" href="/_nuxt/vendors.app.js" as="script">
<link rel="preload" href="/_nuxt/app.js" as="script">

Kehren wir zurück zur Datei [nuxt.config]:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    ...
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: [],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Doc: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
}
  • Zeile 12: Zwischen jeder Route im [nuxt]-Client erscheint eine Ladeleiste, wenn der Routenwechsel etwas Zeit in Anspruch nimmt. Mit der Eigenschaft [loading] kannst du diese Ladeleiste konfigurieren; hier die Farbe der Leiste;
  • Zeile 16: die globalen [css]-Dateien. Sie werden automatisch in alle Seiten der Anwendung eingebunden;
  • Zeilen 24–27: die für die Erstellung der Anwendung erforderlichen JavaScript-Module;
  • Zeilen 31–36: die von der Anwendung verwendeten JavaScript-Module;
  • Zeile 41: Konfiguration der [axios]-Bibliothek, wenn diese vom Benutzer für HTTP-Interaktionen mit Servern von Drittanbietern ausgewählt wurde;
  • Zeilen 45–50: Projekt-Build-Konfiguration;

Sie können der Konfigurationsdatei weitere Schlüssel hinzufügen. Insbesondere können Sie den Service-Port (standardmäßig 3000) und das Projektverzeichnis (standardmäßig der Stammordner des Projekts) konfigurieren. Genau das werden wir nun tun, indem wir die folgenden Schlüssel hinzufügen:


// source code directory
  srcDir: '.',
  router: {
    // URL root of application pages
    base: '/nuxt-intro/'
  },
  // server
  server: {
    // service port - default 3000
    port: 81,
    // network addresses listened to - default localhost=127.0.0.1
    host: '0.0.0.0'
  }
  • Zeile 2: Wo sich der Quellcode des Projekts befindet. Er befindet sich hier im aktuellen Verzeichnis, d. h. auf derselben Ebene wie die Datei [nuxt.config.js]. Dies ist der Standardwert;
  • Zeilen 8–13: Konfigurieren Sie den Server (beachten Sie, dass eine [nuxt]-Anwendung vom Typ [universal] sowohl auf einem Server als auch in einem Client-Browser installiert ist);
  • Zeile 10: Die Seiten der Anwendung werden auf Port 81 des Servers bereitgestellt;
  • Zeile 12: standardmäßig [localhost] (Netzwerkadresse 127.0.0.1). Ein Rechner kann mehrere Netzwerkadressen haben, wenn er zu mehreren Netzwerken gehört. Die Adresse 0.0.0.0 bedeutet, dass der Webserver auf allen Netzwerkadressen des Rechners lauscht;
  • Zeilen 3–6: Konfigurieren des [nuxt]-Anwendungsrouters;
  • Zeile 5: Die Seiten der Anwendung sind unter der URL [http://localhost:81/nuxt-intro/] verfügbar;

Fügen wir diese Zeilen in die Datei [nuxt.config.js] ein und führen wir dann das Projekt aus (npm dev-Skript). Das Ergebnis sieht wie folgt aus:

Image

  • [1] ist die Adresse des Rechners in einem öffentlichen Netzwerk;
  • in [2] der Dienstport;
  • in [3] die Root-URL der Anwendung;

3.4. Der Ordner [layouts]

Image

Der Ordner [layouts] ist für Layout-Komponenten vorgesehen. Standardmäßig wird die Komponente mit dem Namen [default.vue] verwendet. In diesem Projekt sieht das wie folgt 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>

Kommentare

  • Zeilen 1–5: die [Vorlage] der Komponente;
  • Zeile 3: Das <nuxt />-Tag bezeichnet die aktuelle Routing-Seite;
  • Zeilen 7–55: der von der Layout-Komponente eingebettete Stil. Da diese Komponente die aktuelle Routing-Seite enthält, gilt dieser Stil für alle gerouteten Seiten in der Anwendung;

Wir sehen, dass der Hauptzweck der Seite [default.vue] hier darin besteht, einen Stil auf geroutete Seiten anzuwenden.

3.5. Der Ordner [pages]

Image

Der Ordner [pages] enthält die gerouteten Ansichten, die der Benutzer sieht. Die Seite [index.vue] ist die Startseite der Anwendung. Bei [nuxt.js] gibt es keine Routing-Datei. Routen werden anhand der Struktur des Ordners [pages] festgelegt. Hier erstellt das Vorhandensein einer Datei [index.vue] automatisch eine Route namens [index] mit dem Pfad [/index], der zu [/] verkürzt wird, da es sich um die Startseite handelt. Somit wird die folgende Route erstellt:

        { name : ‘index’, path : ‘/’}

Die Datei [index.vue] sieht wie folgt aus:


<template>
  <div class="container">
    <div>
      <logo />
      <h1 class="title">
        nuxt-intro
      </h1>
      <h2 class="subtitle">
        nuxt-intro
      </h2>
      <div class="links">
        <a href="https://nuxtjs.org/" target="_blank" class="button--green">
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >
          GitHub
        </a>
      </div>
    </div>
  </div>
</template>
 
<script>
import Logo from '~/components/Logo.vue'
 
export default {
  components: {
    Logo
  }
}
</script>
 
<style>
.container {
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
 
.title {
  font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
    'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  display: block;
  font-weight: 300;
  font-size: 100px;
  color: #35495e;
  letter-spacing: 1px;
}
 
.subtitle {
  font-weight: 300;
  font-size: 42px;
  color: #526488;
  word-spacing: 5px;
  padding-bottom: 15px;
}
 
.links {
  padding-top: 15px;
}
</style>

Die [Vorlage] in den Zeilen 1–25 zeigt die folgende Ansicht an:

Image

Das Bild [1] wird durch Zeile 4 der [Vorlage] generiert. Wir sehen, dass die Seite eine Komponente namens [logo] verwendet. Diese ist in den Zeilen 27–35 des Skripts der Seite definiert. In Zeile 28 bezieht sich die Notation [~] auf das Projektverzeichnis.

Image

Die Komponente [Logo.vue] sieht wie folgt aus:


<template>
  <div class="VueToNuxtLogo">
    <div class="Triangle Triangle--two" />
    <div class="Triangle Triangle--one" />
    <div class="Triangle Triangle--three" />
    <div class="Triangle Triangle--four" />
  </div>
</template>
 
<style>
.VueToNuxtLogo {
  display: inline-block;
  animation: turn 2s linear forwards 1s;
  transform: rotateX(180deg);
  position: relative;
  overflow: hidden;
  height: 180px;
  width: 245px;
}
 
.Triangle {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
}
 
.Triangle--one {
  border-left: 105px solid transparent;
  border-right: 105px solid transparent;
  border-bottom: 180px solid #41b883;
}
 
.Triangle--two {
  top: 30px;
  left: 35px;
  animation: goright 0.5s linear forwards 3.5s;
  border-left: 87.5px solid transparent;
  border-right: 87.5px solid transparent;
  border-bottom: 150px solid #3b8070;
}
 
.Triangle--three {
  top: 60px;
  left: 35px;
  animation: goright 0.5s linear forwards 3.5s;
  border-left: 70px solid transparent;
  border-right: 70px solid transparent;
  border-bottom: 120px solid #35495e;
}
 
.Triangle--four {
  top: 120px;
  left: 70px;
  animation: godown 0.5s linear forwards 3s;
  border-left: 35px solid transparent;
  border-right: 35px solid transparent;
  border-bottom: 60px solid #fff;
}
 
@keyframes turn {
  100% {
    transform: rotateX(0deg);
  }
}
 
@keyframes godown {
  100% {
    top: 180px;
  }
}
 
@keyframes goright {
  100% {
    left: 70px;
  }
}
</style>

Diese Komponente besteht hauptsächlich aus Stilen und Animationen, um ein animiertes Bild zu erstellen.

3.7. Vue DevTools

[Vue DevTools] ist die Browser-Erweiterung, mit der Sie [nuxt.js]- und [vue.js]-Objekte im Browser untersuchen können. Wir haben sie bereits im Kapitel über [vue.js] verwendet. Schauen wir uns an, was dieses Tool findet, wenn die Startseite unserer App angezeigt wird:

Image

  • In [1] verweist die Komponente [PagesIndex] auf die Seite [pages/index.vue];
  • in [2] sehen wir, dass diese Komponente eine [$route]-Eigenschaft hat, die die Route angibt, die zur [index]-Seite geführt hat;

Als einfache Übung wollen wir diese Route in der Konsole anzeigen.

3.8. Die Startseite ändern

Wir werden die Datei [index.vue] ändern. In unserer Projekteinrichtung haben wir zwei Abhängigkeiten installiert:

  • [eslint]: Diese überprüft die Syntax von JavaScript-Dateien und Vue-Komponenten. Wenn die [ESLint]-Erweiterung für VSCode installiert ist, wird die Syntax während der Eingabe überprüft und Fehler werden sofort markiert;
  • [prettier]: formatiert JavaScript-Code auf standardisierte Weise;

Diese Abhängigkeiten sind in der Datei [package.json] aufgeführt:


"devDependencies": {
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "eslint-plugin-prettier": "^3.0.1",
    "prettier": "^1.16.4"
}

Mir ist aufgefallen (Nov. 2019), dass bei der Installation über den Befehl [yarn create nuxt-app] die Tools [eslint, prettier] während der Eingabe nicht funktionieren. Fehler werden erst bei der Kompilierung gemeldet. Nach einigen Recherchen habe ich eine Konfiguration gefunden, die funktioniert:

Image

Erstelle einen Ordner [.vscode] im Projektstammverzeichnis und lege darin die folgende Datei [settings.json] ab:


{
  "eslint.validate": [
    {
      "language": "vue",
      "autoFix": true
    },
    {
      "language": "javascript",
      "autoFix": true
    }
  ],
  "eslint.autoFixOnSave": true,
  "editor.formatOnSave": false
}
  • Zeilen 2–11: Legen fest, dass [eslint] bei der Validierung von .vue- und .js-Dateien alle möglichen Fehler beheben soll;
  • Zeile 12: Beim Speichern einer Datei soll [eslint] alle möglichen Fehler beheben;
  • Zeile 13: Deaktiviert die Standardformatierung in VSCode beim Speichern. [prettier] übernimmt dies stattdessen;

Mit dieser Konfiguration:

  • werden Syntax- oder Formatierungsfehler sofort nach der Eingabe des Textes markiert;
  • Formatierungsfehler werden beim Speichern der Datei automatisch korrigiert;

Die [prettier]-Bibliothek wird über die Datei [.prettierrc] konfiguriert:

Image

Standardmäßig sieht diese Datei wie folgt aus:


{
  "semi": false,
  "arrowParens": "always",
  "singleQuote": true
}
  • Zeile 1: kein Semikolon am Ende von Anweisungen;
  • Zeile 2: Wenn eine Pfeilfunktion einen einzigen Parameter hat, wird dieser in Klammern gesetzt;
  • Zeile 3: Zeichenfolgen werden in einfache Anführungszeichen gesetzt (nicht in doppelte Anführungszeichen);

Wir fügen die folgenden zwei Regeln hinzu:


{
  "semi": false,
  "arrowParens": "always",
  "singleQuote": true,
  "printWidth": 120,
  "endOfLine": "auto"
}
  • Zeile 5: Die Codezeile darf bis zu 120 Zeichen lang sein;
  • Zeile 6: Das Zeilenendezeichen kann entweder CRLF (Windows) oder LF (Unix) sein;

Schließlich wird die Datei [package.json] wie folgt geändert:


"scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."
},
  • Zeile 7: Wir fügen den Befehl [lintfix] hinzu, der mit dem Befehl [lint] in Zeile 6 identisch ist, außer dass er den Parameter [--fix] enthält. Der Befehl [lint] überprüft die Syntax und Formatierung aller Dateien im Projekt und meldet etwaige Fehler. [lintfix] macht dasselbe, mit dem Unterschied, dass alle Formatierungsprobleme, die korrigiert werden können, automatisch behoben werden. [lintfix] ist der Befehl, den Sie verwenden sollten, wenn der Build aufgrund von Formatierungsproblemen in den Dateien fehlschlägt;

Anschließend ändern wir die Datei [index.vue] wie folgt:

Image


<script>
/* eslint-disable no-console */
import Logo from '~/components/Logo.vue'
 
export default {
  components: {
    Logo
  },
  // cycle de vie
  created() {
    console.log('created, route=', this.$route)
  }
}
</script>
  • Zeilen 10–12: Wir fügen die Funktion [created] hinzu, die automatisch ausgeführt wird, wenn die Komponente erstellt wird;
  • Zeile 11: Wir zeigen die aktuelle Route an;
  • Zeile 2: Ein Kommentar für [eslint]. Ohne diesen Kommentar meldet [eslint] einen Fehler. Zeile 11: [eslint] erlaubt keine [console]-Anweisungen in Lebenszyklusfunktionen. [eslint] ist konfigurierbar. Wir behalten die Standardkonfiguration bei und verwenden Kommentare wie den in Zeile 2, um eine bestimmte [eslint]-Regel zu deaktivieren. Wir verwenden zwei Arten von Kommentaren:
    • /* [eslint]-Regel deaktivieren */: deaktiviert eine Regel für die gesamte Datei;
    • // [eslint]-Regel deaktivieren: deaktiviert eine Regel für die folgende Zeile;

Während der Eingabe werden Fehler markiert und eine [Quick Fix]-Funktion steht zur Verfügung:

Image

Projekt ausführen:

Image

  • in [1], die Registerkarte [Ansicht] der Entwicklertools des Browsers (F12);
  • in [2] und [3] die Routenanzeige;

Warum zwei Ansichten statt nur einer?

Eine [Nuxt]-Anwendung besteht aus zwei Komponenten, einem Server und einem Client:

  1. Der Server stellt die Seiten der Anwendung bereit, wenn die Anwendung gestartet wird und anschließend jedes Mal, wenn eine Seite im Browser aktualisiert wird (F5) oder der Benutzer manuell eine Anwendungs-URL eingibt;
  2. Jede vom Browser bereitgestellte Seite enthält die angeforderte Seite sowie den JavaScript-Code für die gesamte Anwendung, der dann im Browser ausgeführt wird. Dies ist der Client. Solange keine Seitenaktualisierung im Browser stattfindet, funktioniert die Anwendung wie eine klassische Vue-Anwendung im [SPA]-Modus (Single Page Application). Sobald der Benutzer manuell eine Seitenaktualisierung auslöst, wird die Seite vom Server angefordert, und wir kehren zum vorherigen Schritt 1 zurück.

Man muss verstehen, dass es sich um dieselben Seiten aus dem Ordner [pages] handelt, die entweder vom Server oder vom Client bereitgestellt werden. Aus diesem Grund bezeichnen die Entwickler von [nuxt] diese Art von Seite als isomorphe Seite. Dieselben [.vue]-Seiten können sowohl vom Client als auch vom Server interpretiert werden. Nehmen wir das Beispiel der [index]-Seite:


<template>
  <div class="container">
    <div>
      <logo />
      <h1 class="title">
        nuxt-intro
      </h1>
      <h2 class="subtitle">
        nuxt-intro
      </h2>
      <div class="links">
        <a href="https://nuxtjs.org/" target="_blank" class="button--green">
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          class="button--grey"
        >
          GitHub
        </a>
      </div>
    </div>
  </div>
</template>
 
<script>
/* eslint-disable no-console */
import Logo from '~/components/Logo.vue'
 
export default {
  components: {
    Logo
  },
  // cycle de vie
  created() {
    console.log('created, route=', this.$route)
  }
}
</script>

Da es sich um die Startseite handelt, wird sie vom Server beim Start der Anwendung bereitgestellt. Die Seite auf dem Server hat ebenfalls einen Lebenszyklus, der dem einer klassischen [Vue]-Seite entspricht, mit Ausnahme der Funktionen [beforeMount] und [mounted], die auf der Serverseite nicht vorhanden sind. Die Funktion [created] wird ausgeführt, was den ersten Log-Eintrag erklärt. Das bedeutet übrigens, dass der Server in der Lage ist, JavaScript-Skripte auszuführen. Hier und generell handelt es sich bei diesem Server um einen [node.js]-Server. Sobald die Seite auf dem Server erstellt wurde, gelangt sie in den Browser, wo sie erneut den Lebenszyklus durchläuft. Die Funktion [created] wird ein zweites Mal ausgeführt, was den zweiten Log-Eintrag erzeugt.

Die Architektur einer [nuxt]-Anwendung könnte wie folgt aussehen:

Image

  • [1]: der Browser, der die [nuxt]-Anwendung hostet, sobald sie in den Browser geladen wurde. Dies bezeichnen wir als den [nuxt]-Client;
  • [3]: der Server, der die [nuxt]-Anwendung ursprünglich hostet. Sie wird in den Browser [1] geladen, wenn die Anwendung startet und jedes Mal, wenn der Benutzer die aktuelle Browserseite aktualisiert oder manuell eine Anwendungs-URL eingibt. Hier liegt der Unterschied in der Funktionsweise im Vergleich zu einer klassischen Vue-Anwendung. Bei einer klassischen Vue-Anwendung wurde der Server, sobald die Anwendung in den Browser geladen war, nie wieder aufgerufen. Ein weiterer wichtiger Unterschied, den wir bisher noch nicht gesehen haben, besteht darin, dass der Server für eine Vue-Anwendung ein statischer Server ist, der keine [.vue]-Seiten interpretieren kann, während der Server für eine [universelle] Nuxt-Anwendung ein JavaScript-Server ist. Bevor eine Seite an den Browser gesendet wird, kann der Server Skripte ausführen und beispielsweise Daten vom Server [2] abrufen;
  • [2]: ist der Server, der Daten entweder an den [nuxt]-Client [1] oder an den [nuxt]-Server [3] liefert;

In der obigen Abbildung lassen sich drei Client/Server-Subsysteme unterscheiden:

  • [1, 3]: hostet die [nuxt]-Anwendung. [3] stellt sie bereit, wenn die Anwendung mit der Startseite startet und jedes Mal, wenn der Benutzer manuell eine Seite anfordert. [1] hostet die von [3] empfangene [nuxt]-Anwendung, die dann im [SAP]-Modus arbeitet, solange keine Seiten manuell von [3] angefordert werden;
  • [1, 2]: Im [SAP]-Modus ruft der [nuxt]-Client externe Daten von einem oder mehreren Servern ab;
  • [3, 2]: Bei der Generierung der vom Benutzer angeforderten Seite kann Server [3] ebenfalls externe Daten von einem oder mehreren Servern abrufen;

Es ist also der Server [3], der eine [Nuxt]-Anwendung von einer [Vue]-Anwendung unterscheidet. Dieser Server wird jedes Mal aufgerufen, wenn der Benutzer manuell eine Seite anfordert. Er verarbeitet dieselben [.vue]-Seiten wie der [Vue]-Client [1]. Es handelt sich um einen JavaScript-Server, der in der Lage ist, die auf der Seite vorhandenen Skripte auszuführen. Dies kann beispielsweise die Art und Weise verändern, wie die Startseite unter Verwendung externer Daten generiert wird: Während eine [Vue]-Anwendung diese Daten zwangsläufig vom Client [1] abruft, können sie hier vom Server [3] abgerufen werden, bevor die Seite an den Client gesendet wird. Die Startseite gewinnt dadurch an Aussagekraft und kann dazu beitragen, die SEO der Anwendung zu verbessern.

Hinweis: Im Entwicklungsmodus befinden sich die drei Komponenten [1, 2, 3] oft auf demselben Rechner. Dies ist hier bei allen unseren Beispielen der Fall.

3.9. Verschieben des Quellcodes der Anwendung in einen separaten Ordner

Als Nächstes erstellen wir verschiedene [nuxt]-Anwendungen im selben [dvp]-Ordner. Der Grund dafür ist, dass der für jedes [nuxt]-Projekt generierte Abhängigkeitsordner [node_modules] mehrere hundert Megabyte groß sein kann. Wir werden verschiedene Ordner [nuxt-00, nuxt-01, ...] innerhalb des [dvp]-Ordners erstellen, um den Quellcode für die zu testenden Beispiele zu speichern. Anschließend werden wir die Konfigurationsdatei [nuxt-config.js] verwenden, um den Speicherort des Quellcodes für das [dvp]-Projekt anzugeben, das in diesem Tutorial das einzige [nuxt]-Projekt bleiben wird.

Wir verschieben den Quellcode der Anwendung, der ursprünglich mit dem Befehl [yarn create nuxt-app] generiert wurde, in einen Ordner [nuxt-00]:

Image

  • In [2] haben wir die Ordner [components, layouts, pages] in einen Ordner [nuxt-00] verschoben;
  • In [3] müssen wir die Datei [nuxt.config.js] ändern;

Wir ändern die Datei [nuxt.config.js] wie folgt:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  ...
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  },
  // source code directory
  srcDir: 'nuxt-00',
  // router
  router: {
    // application URL root
    base: '/nuxt-00/'
  },
  // server
  server: {
    // service port, default 3000
    port: 81,
    // network addresses listened to, default localhost: 127.0.0.1
    // 0.0.0.0 = all the machine's network addresses
    host: '0.0.0.0'
  }
}

Die Datei wird an zwei Stellen geändert:

  • Zeile 17: Wir geben an, dass sich der Quellcode für das [dvp]-Projekt im Ordner [nuxt-00] befindet;
  • Zeile 21: Wir geben an, dass die Stamm-URL der Anwendung nun [/nuxt-00/] lautet. Diese Änderung war nicht zwingend erforderlich. Wir hätten diese Eigenschaft weglassen können; in diesem Fall wäre die Stamm-URL [/] gewesen. Hier hilft uns dies dabei, uns daran zu erinnern, dass der ausgeführte Quellcode aus dem Ordner [nuxt-00] stammt;

Sobald dies erledigt ist, wird das [dvp]-Projekt wie zuvor ausgeführt:

Image

3.10. Bereitstellung der [nuxt-00]-Anwendung

Wir werden die Anwendung [nuxt-00] in einer anderen Umgebung als der in VSCode integrierten Umgebung ausführen.

Zunächst kompilieren wir die Anwendung:

Image

  • in [3] das Ergebnis der Client-Kompilierung. Dies wird vom Browser ausgeführt;
  • in [4] das Ergebnis der Serverkompilierung. Dies wird vom [node.js]-Server ausgeführt;

Die Kompilierungsergebnisse werden im Ordner [.nuxt] abgelegt:

Image

Wir kopieren die Ordner [.nuxt, node_modules] und die Dateien [package.json, nuxt.config.js] in einen separaten Ordner:

Image

Die Datei [package.json] wird wie folgt vereinfacht:


{
  "scripts": {
    "start": "nuxt start"
  }
}
  • Wir behalten nur das Skript [start] bei, das die kompilierte Version des Projekts ausführt;

Die Datei [nuxt.config.js] wird wie folgt vereinfacht:


export default {
  // router
  router: {
    // application URL root
    base: '/nuxt-00/'
  },
  // server
  server: {
    // service port, default 3000
    port: 81,
    // network addresses listened to, default localhost: 127.0.0.1
    // 0.0.0.0 = all the machine's network addresses
    host: '0.0.0.0'
  }
}
  • Zeile 5: Legt die Basis-URL der kompilierten Anwendung fest;
  • Zeilen 8–14: definieren den Dienstport und die Netzwerkadressen, auf denen abgehört werden soll;

Sobald dies erledigt ist, öffnen Sie ein Laragon-Terminal und navigieren Sie zu dem Ordner, der die kompilierte Version des Projekts enthält. Sie können jede Art von Terminal öffnen, aber die ausführbare Datei [npm] muss sich im PATH des Terminals befinden. Dies ist beim Laragon-Terminal der Fall.

Geben Sie anschließend den Befehl [npm run start] ein:

Image

In [3] sehen wir, dass ein Server gestartet wurde und unter der URL [http://192.168.1.128:81/nuxt-00/] auf Anfragen wartet. Rufen wir nun diese URL mit einem Browser auf [4]. Wir sehen das gleiche Ergebnis wie zuvor. Im Terminal wurden Protokolle geschrieben [5]. Dies ist das Protokoll, das in der Methode [created] der Seite [index.vue] platziert wurde und vom [node.js]-Server ausgeführt wurde.

Image

Auf der Browserseite [6] sehen wir ebenfalls das Protokoll aus der [created]-Methode der Seite [index.vue], diesmal jedoch vom Client ausgeführt.

3.11. Einrichten eines sicheren Servers

Oben lautet die URL der Anwendung [http://192.168.1.128/nuxt-00/]. Wir möchten, dass sie [https://192.168.1.128/nuxt-00/] lautet. Daher müssen wir einen sicheren Server einrichten. So geht das.

Hinweis: Diese Methode stammt aus dem Artikel [https://stackoverflow.com/questions/56966137/how-to-run-nuxt-npm-run-dev-with-https-in-localhost].

Zunächst erstellen wir mit [openssl] einen privaten und einen öffentlichen Schlüssel. [openssl] wird normalerweise zusammen mit dem Laragon-Server installiert. Daher ist dieser Befehl in jedem Laragon-Terminal verfügbar. Öffnen wir also ein Laragon-Terminal und wechseln wir in den Ordner der bereitgestellten Anwendung:

Image

Image

  • Geben Sie in [2] den Befehl [openssl genrsa 2048 > server.key] ein;
  • in [3] wird eine Datei [server.key] erstellt;
  • Geben Sie in [4] den Befehl [openssl req -new -x509 -nodes -sha256 -days 365 -key server.key -out server.crt] ein;
  • in [5] wird eine Datei namens [server.crt] erstellt;

Diese beiden Dateien bilden ein selbstsigniertes Zertifikat. Die meisten Browser akzeptieren sie erst nach der Zustimmung des Benutzers, der die Seite aufgerufen hat.

Die Dateien [server.key, server.crt] müssen nun von der Webanwendung verwendet werden. Dazu muss die Datei [nuxt.config.js] wie folgt geändert werden:


import path from 'path'
import fs from 'fs'
 
export default {
  // router
  router: {
    // application URL root
    base: '/nuxt-00/'
  },
  // server
  server: {
    // service port, default 3000
    port: 81,
    // network addresses listened to, default localhost: 127.0.0.1
    // 0.0.0.0 = all the machine's network addresses
    host: '0.0.0.0',
    // self-signed certificate
    https: {
      key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
      cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
    }
  }
}

Die Zeilen 18–21 implementieren das [https]-Protokoll.

Führen wir die Anwendung nun erneut aus:

Image

3.12. Ende des ersten Beispiels

Das erste Beispiel ist nun abgeschlossen. Es hat uns viele [nuxt]-Konzepte vermittelt. Wir werden nun weitere Beispiele entwickeln, die wir in den Ordnern [nuxt-01, nuxt-02, ...] ablegen werden. Da diese Beispiele eine andere [nuxt.config.js]-Datei verwenden, speichern wir die [nuxt.config.js]-Datei, die zum Ausführen der einzelnen Beispiele verwendet wird, in den jeweiligen Ordnern:

Image