Nuxt.js App vom UI-Kit bis zur Bereitstellung

Hallo Habr!



Ich habe dieses detaillierte, schrittweise Tutorial geschrieben, damit jeder seine eigene Anwendung mit dem Nuxt.js-Framework von Grund auf neu erstellen kann.



In diesem Artikel werden die Grundlagen und Grundlagen zum Erstellen einer Nuxt.js-Anwendung erläutert:



  • Projekterstellung und -konfiguration,
  • Assets und statische: Stile, Schriftarten, Bilder, Beiträge,
  • Komponenten erstellen,
  • Erstellen von Seiten und Layouts,
  • Anwendungsbereitstellung (Bereitstellung).


Sehen Sie, was passiert ist!



Ein wenig über Nuxt.js



Nuxt ist ein Vue-Framework auf hoher Ebene. Mit Nuxt.js können Sie sofort isomorphe Webanwendungen entwickeln, indem Sie die Verteilungsdetails des Server- und Client-Codes abstrahieren. Dank dieses Ansatzes sparen wir Zeit und können uns auf die Entwicklung konzentrieren.



Die Hauptvorteile von Nuxt:



  • SPA, SSR und Prerender sind bereits konfiguriert. Alles, was von uns verlangt wird, ist anzugeben. In dieser Anwendung verwenden wir einen Prerender für den Produktmodus. Das heißt, wir generieren alle Seiten der Site im Voraus und stellen sie dann auf dem Hosting bereit, um Statiken zu verteilen.
  • Hervorragende Suchmaschinenoptimierung für alle Suchmaschinen ist das Ergebnis der Verwendung von SSR oder Pre-Renderer.
  • . js chunks, css styles API ( webpack 4, Nuxt).
  • Google Lighthouse / Page Speed. 100/100 .
  • CSS Modules, Babel, Postscc create-nuxt-app.
  • .
  • 50 Vue.js.


Wir können sehr lange über die Vorteile von Nuxt sprechen. Dies ist das Framework, das ich wegen seiner Benutzerfreundlichkeit und der Fähigkeit, flexible und leicht skalierbare Anwendungen zu erstellen, wirklich liebe. Daher schlage ich vor, alle Vorteile in der Praxis zu nutzen.

Weitere Informationen zu Nuxt.js finden Sie auf der offiziellen Website . Detaillierte Anleitungen finden Sie auch hier .



Design



Ein durchdachtes, vorgefertigtes Design oder noch besser ein UI-Kit beschleunigt und vereinfacht die Entwicklung jeder Anwendung erheblich. Wenn es keinen kostenlosen UI-Designer in der Nähe gibt, ist das in Ordnung. Im Rahmen unserer Anweisungen können wir selbst damit umgehen!



Speziell für diesen Artikel habe ich ein Blog-Design in einem modernen, minimalistischen Stil mit einfacher Funktionalität erstellt, das ausreicht, um die Fähigkeiten von Nuxt zu demonstrieren.



Für die Entwicklung habe ich den Figma-Onlinedienst verwendet. Das Design und das UI-Kit finden Sie hier . Sie können diese Vorlage kopieren und in Ihrem Projekt verwenden.



Projekterstellung



Um ein Projekt zu erstellen, verwenden wir das Dienstprogramm Nuxt create-nuxt-app der Nuxt-Entwickler , mit dem wir die Anwendungsvorlage über die CLI konfigurieren können.



Wir initialisieren das Projekt, indem wir seinen Namen angeben:



npx create-nuxt-app nuxt-blog
      
      





Darüber hinaus bietet uns das Dienstprogramm in mehreren Schritten die Auswahl einer Reihe bevorzugter Bibliotheken und Pakete an. Anschließend werden diese unabhängig voneinander heruntergeladen, konfiguriert und für das Projekt konfiguriert.



Sie können eine vollständige Liste der ausgewählten Optionen auf Github sehen .



Für dieses Projekt wird die Konfiguration mit Typescript verwendet.



Bei der Entwicklung in Vue mit Typescript können Sie zwei APIs verwenden: Options-API oder Klassen-API .



Sie unterscheiden sich funktional nicht voneinander, haben aber unterschiedliche Syntax. Persönlich ist mir die Options-API-Syntax näher, sodass sie in unserem Projekt verwendet wird.



Nach dem Erstellen des Projekts können wir unsere Anwendung mit dem folgenden Befehl ausführen: npm run dev. Es wird jetzt auf localhost verfügbar sein: 3000.



Nuxt verwendet einen Webpack-Dev-Server, auf dem HMR installiert und als lokaler Server konfiguriert ist , was die Entwicklung schnell und komfortabel macht.



Da wir eine Demoversion der Anwendung erstellen, werde ich keine Tests dafür schreiben. Ich empfehle jedoch dringend, Anwendungstests in der kommerziellen Entwicklung nicht zu vernachlässigen.



Wenn Sie dieses Thema noch nicht angesprochen haben, empfehle ich Ihnen, auf Jest zu achten - ein sehr einfaches, aber gleichzeitig leistungsstarkes Tool, das die Arbeit mit Nuxt in Verbindung mit unterstützt vue-test-utils .



Projektstruktur



Nuxt erstellt standardmäßig eine Verzeichnis- und Dateistruktur, die für einen schnellen Start in die Entwicklung geeignet ist. Für unser Projekt passt eine solche Struktur perfekt, daher werden wir sie nicht ändern. Weitere Informationen zum Zweck verschiedener Verzeichnisse finden Sie auf der Nuxt-Website .



-- Assets

-- Static

-- Pages

-- Middleware

-- Components

-- Layouts

-- Plugins

-- Store

-- nuxt.config.js

-- ...other files














Anwendungserstellung



Bevor Sie den Code schreiben, gehen Sie wie folgt vor:



1. Entfernen Sie die von Nuxt generierten Starterkomponenten und Seiten.

2. Installieren Sie mops und scss für unsere Bequemlichkeit und um Zeit während der Entwicklung zu sparen. Führen wir den Befehl aus:



npm i --save-dev pug pug-plain-loader node-sass sass-loader fibers
      
      





Danach wird die Verwendung des lang-Attributs für die Vorlagen- und Stil-Tags verfügbar:



<template lang="pug"></template>

<style lang="scss"></style>
      
      





3. Fügen Sie der Stylelint-Konfiguration Unterstützung für den :: v-deep deep-Selektor hinzu, mit dem untergeordnete Komponenten gestylt werden können, wobei der Gültigkeitsbereich ignoriert wird. Weitere Informationen zu diesem Selektor finden Sie hier.



{
  rules: {  
    'at-rule-no-unknown': null,  
    'selector-pseudo-element-no-unknown': [  
      true,  
      {  
        ignorePseudoElements: ['v-deep'],  
      },  
    ],  
  },
}
      
      





Alle Vorbereitungen sind abgeschlossen, fahren Sie mit der nächsten Stufe fort.



Beiträge



Beiträge werden im Verzeichnis content / posts gespeichert, das wir im Projektstamm als Satz von Markdown-Dateien erstellen.



Lassen Sie uns 5 kleine Dateien erstellen, damit wir sofort mit ihnen arbeiten können. Der Einfachheit halber verwenden wir die Namen 1.md, 2.md usw.



Erstellen Sie im Inhaltsverzeichnis die Datei Posts.d.ts, in der wir die Typen für das Objekt definieren, die alle erforderlichen Informationen zum Beitrag enthalten:



export type Post = {  
  id: number  
  title: string
  desc: string
  file: string
  img: string  
}
      
      





Ich denke, dass die Bedeutung aller Felder aus den Namen klar hervorgehen sollte.



Mach weiter. Erstellen Sie im selben Verzeichnis eine weitere Datei mit dem Namen posts.ts mit folgendem Inhalt:



import { Post } from './Post'  

export default [  
  {
    id: 1,  
    title: 'Post 1',  
    desc:  
      'A short description of the post to keep the user interested.' +  
      ' Description can be of different lengths, blocks are aligned' +  
      ' to the height of the block with the longest description',  
    file: 'content/posts/1.md',
    img: 'assets/images/1.svg',
  },  

  ...

  {  
    id: 5,  
    title: 'Post 5',  
    desc:  
      'A short description of the post to keep the user interested.' +  
      ' Description can be of different lengths, blocks are aligned' +  
      ' to the height of the block with the longest description',  
    file: 'content/posts/5.md',
    img: 'assets/images/5.svg',
  },  
] as Post[]
      
      





In der Eigenschaft img verweisen wir auf Bilder im Verzeichnis Assets / Images, aber wir haben dieses Verzeichnis noch nicht erstellt. Lassen Sie es uns jetzt tun.



Fügen wir nun die Bilder im SVG-Format mit den oben angegebenen Namen zum erstellten Verzeichnis hinzu.



Ich werde 5 Bilder von unDraw machen . Diese hervorragende Ressource wird ständig aktualisiert und enthält viele kostenlose SVG-Bilder.



Nachdem alles fertig ist, sollte das Inhaltsverzeichnis folgendermaßen aussehen: Das Unterverzeichnis images sollte im Asset-Verzeichnis mit folgendem Inhalt angezeigt werden:



content/

-- posts.ts

-- Posts.d.ts

-- posts/

---- 1.md

---- 2.md

---- 3.md

---- 4.md

---- 5.md












assets/

-- images/

---- 1.svg

---- 2.svg

---- 3.svg

---- 4.svg

---- 5.svg

...








Dateien dynamisch abrufen



Da wir Bilder und Dateien mit dem Text von Posts dynamisch empfangen, müssen wir ein globales Mixin implementieren, das wir in allen Komponenten weiter verwenden können.



Erstellen Sie dazu ein Plugins-Unterverzeichnis im Plugins-Verzeichnis und darin eine getDynamicFile.ts-Datei mit folgendem Inhalt:



import Vue from 'vue'  
  
export const methods = {  
  getDynamicFile(name: string) {  
    return require(`@/${name}`)
 },  
}  
  
Vue.mixin({  
  methods,  
})
      
      





Wir müssen nur noch dieses Mixin in der Datei nuxt.config.js aktivieren:



{
  plugins: [  
    '~plugins/mixins/getDynamicFile.ts',  
  ],
}
      
      





Schriftarten



Verbinden Sie nach dem Erstellen der Beiträge die Schriftarten. Der einfachste Weg, dies zu tun, ist die wunderbare Webfontloader- Bibliothek , mit der Sie jede Schriftart von Google Fonts abrufen können . In der kommerziellen Entwicklung werden jedoch häufig benutzerdefinierte Schriftarten verwendet. Schauen wir uns hier also nur diesen Fall an.



Rubik wurde als Schriftart für unsere Anwendung ausgewählt, die unter der Open Font License vertrieben wird . Sie können alles von denselben Google Fonts herunterladen .



Bitte beachten Sie, dass in die heruntergeladenen die Schriftarten Archiv im OTF - Format sein wird, aber da wir mit der Bahn arbeiten, werden die woff und woff2 Formaten die beste Wahl für uns. Sie sind kleiner als alle anderen Formate, sind aber perfekt unterstützt in alle modernen Browser. Um otf in die von uns benötigten Formate zu konvertieren, können Sie einen der vielen kostenlosen Online-Dienste nutzen.



Wir haben also die Schriftarten in den Formaten, die wir benötigen. Es ist Zeit, sie in das Projekt aufzunehmen. Erstellen Sie dazu ein Unterverzeichnis für Schriftarten im statischen Verzeichnis und fügen Sie dort unsere Schriftarten hinzu. Erstellen wir eine fonts.css-Datei im selben Verzeichnis, die für die Verbindung unserer Schriftarten in der Anwendung mit dem folgenden Inhalt verantwortlich ist:



@font-face {  
  font-family: "Rubik-Regular";  
  font-weight: normal;  
  font-style: normal;  
  font-display: swap;  
  src:  
	  local("Rubik"),  
	  local("Rubik-Regular"),  
	  local("Rubik Regular"),  
	  url("/fonts/Rubik-Regular.woff2") format("woff2"),  
	  url("/fonts/Rubik-Regular.woff") format("woff");  
}  
  
...
      
      





Der vollständige Inhalt der Datei wird im Repository angezeigt .



Es gibt zwei Dinge, die Sie beachten sollten:



1. Wir geben die Schriftartenanzeige an: swap; und definieren, wie die über die Schriftfläche verbundene Schrift angezeigt wird, je nachdem, ob sie geladen und einsatzbereit ist.

In diesem Fall legen wir die Blockierungsperiode und keine unendliche Substitutionsperiode fest. Das heißt, das Laden der Schriftart erfolgt im Hintergrund und blockiert das Laden der Seite nicht. Die Schriftart wird angezeigt, wenn sie fertig ist.



2. In src geben wir die Startreihenfolge nach Priorität an. Zunächst überprüfen wir, ob die gewünschte Schriftart auf dem Gerät des Benutzers installiert ist, indem wir die möglichen Varianten des Schriftartnamens prüfen. Wenn wir es nicht finden, prüfen wir, ob der Browser das modernere woff2-Format unterstützt. Wenn nicht, wechseln wir zum nächsten woff-Format. Es besteht die Möglichkeit, dass der Benutzer einen veralteten Browser verwendet (z. B. IE <9). In diesem Fall geben wir im Folgenden die im Browser integrierten Schriftarten als Fallback an.



Nachdem Sie die Datei mit den Regeln zum Laden von Schriftarten erstellt haben, müssen Sie sie in der Anwendung verbinden - in der Datei nuxt.config.js im Kopfbereich:



{
  head: {  
    link: [  
      {  
        as: 'style',  
        rel: 'stylesheet preload prefetch',  
        href: '/fonts/fonts.css',  
      },  
    ],  
  },
}
      
      





Beachten Sie, dass wir hier wie zuvor die Eigenschaften Preload und Prefetch verwenden, um im Browser eine hohe Priorität für das Herunterladen dieser Dateien festzulegen und das Rendern der Seite nicht zu blockieren.



Fügen wir sofort das statische Favicon-Verzeichnis unserer Anwendung hinzu, das mit jedem kostenlosen Onlinedienst generiert werden kann.



Das statische Verzeichnis sieht nun folgendermaßen aus: Fahren Sie mit dem nächsten Schritt fort.



static/

-- fonts/

---- fonts.css

---- Rubik-Bold.woff2

---- Rubik-Bold.woff

---- Rubik-Medium.woff2

---- Rubik-Medium.woff

---- Rubik-Regular.woff2

---- Rubik-Regular.woff

-- favicon.ico












Wiederverwendbare Stile



In unserem Projekt werden alle verwendeten Stile durch einen einzigen Regelsatz beschrieben, was die Entwicklung erheblich erleichtert. Übertragen wir diese Stile daher von Figma in die Projektdateien.

Erstellen Sie im Assets-Verzeichnis ein Unterverzeichnis für Stile, in dem alle wiederverwendeten Stile im Projekt gespeichert werden. Das Styles-Verzeichnis enthält wiederum die Datei variables.scss mit allen unseren scss-Variablen.



Der Inhalt der Datei wird im Repository angezeigt .



Jetzt müssen wir diese Variablen mit dem Projekt verbinden, damit sie in jeder unserer Komponenten verfügbar sind. Zu diesem Zweck verwendet Nuxt das Modul @ nuxtjs / style-resources .



Lassen Sie uns dieses Modul installieren:



npm i @nuxtjs/style-resources
      
      





Fügen Sie nuxt.config.js die folgenden Zeilen hinzu:



{
  modules: [
    '@nuxtjs/style-resources',
  ],

  styleResources: {  
    scss: ['./assets/styles/variables.scss'],  
  },
}
      
      





Fein! Variablen aus dieser Datei sind in jeder Komponente verfügbar.



Der nächste Schritt besteht darin, einige Hilfsklassen und globale Stile zu erstellen, die in der gesamten Anwendung verwendet werden. Mit diesem Ansatz können Sie gängige Stile zentral verwalten und die Anwendung schnell anpassen, wenn das Erscheinungsbild der Layouts vom Designer geändert wird.



Erstellen wir ein globales Unterverzeichnis im Verzeichnis Assets / Styles mit den folgenden Dateien:



1. typography.scss - Die Datei enthält alle Hilfsklassen für Text, einschließlich Links.

Beachten Sie, dass diese Hilfsklassen den Stil abhängig von der Auflösung des Geräts des Benutzers ändern: Smartphone oder PC.



2. transitions.scss - Die Datei enthält globale Animationsstile, sowohl für Übergänge zwischen Seiten als auch für Animationen innerhalb von Komponenten, falls diese in Zukunft benötigt werden.



3. other.scss - Die Datei enthält globale Stile, die noch nicht in einer separaten Gruppe ausgewählt wurden.



Die .page-Klasse wird als gemeinsamer Container für alle Komponenten auf der Seite verwendet und bildet den richtigen Abstand auf der Seite.



Die .section-Klasse wird verwendet, um die Grenzen der logischen Felder zu markieren, und die .content-Klasse wird verwendet, um die Breite des Inhalts einzuschränken und ihn auf der Seite zu zentrieren.



Wir werden später Beispiele dafür sehen, wie diese Klassen verwendet werden, wenn wir mit der Implementierung von Komponenten und Seiten beginnen.



4. index.scss - Eine allgemeine Datei, die als einzelner Exportpunkt für alle globalen Stile verwendet wird.



Der vollständige Inhalt der Dateien kann auf Github eingesehen werden .



In dieser Phase werden wir diese globalen Stile einbeziehen, damit sie in der gesamten Anwendung verfügbar sind. Für diese Aufgabe stellt Nuxt uns einen CSS-Abschnitt in der Datei nuxt.config.js zur Verfügung:



{
  css: ['~assets/styles/global'],
}
      
      





Es ist erwähnenswert, dass in Zukunft beim Zuweisen von CSS-Klassen die folgende Logik verwendet wird:



1. Wenn ein Tag sowohl Hilfsklassen als auch lokale Klassen enthält, werden lokale Klassen direkt zum Tag hinzugefügt, z. B. p .some-local-class und die Hilfsklassen werden in der class -Eigenschaft angegeben, z. B. class = "body3 medium".



2. Wenn ein Tag nur Hilfsklassen oder nur lokale Klassen enthält, werden diese direkt zum Tag hinzugefügt.



Ich benutze diese Technik, um visuell sofort zwischen globalen und lokalen Klassen zu unterscheiden.



Lassen Sie uns vor der Entwicklung reset.css installieren und aktivieren, damit unser Layout in allen Browsern gleich aussieht. Installieren Sie dazu das erforderliche Paket:



npm i reset-css
      
      





Und wir werden es in die Datei nuxt.config.js im bereits bekannten CSS-Abschnitt aufnehmen, der nun so aussieht:



{
  css: [
    '~assets/styles/global',
    'reset-css/reset.css',
  ],
}
      
      





Passiert? Dann sind wir bereit, mit dem nächsten Schritt fortzufahren!



Layouts



In Nuxt sind Layouts Wrapper über Seiten, mit denen Sie gemeinsame Komponenten zwischen ihnen wiederverwenden und die erforderliche gemeinsame Logik implementieren können. Da unsere Anwendung äußerst einfach ist, reicht es aus, das Standardlayout - default.vue - zu verwenden.



Außerdem verwendet Nuxt ein separates Layout für eine Fehlerseite wie 404, die eigentlich eine einfache Seite ist.



Layouts im Repository .



default.vue



Unsere default.vue hat keine Logik und sieht folgendermaßen aus:



<template lang="pug">  
div  
  nuxt
  db-footer
</template>

      
      





Hier verwenden wir 2 Komponenten:



1. nuxt - während der Montage wird es durch eine bestimmte Seite ersetzt, die vom Benutzer angefordert wird.



2.db-footer ist unsere eigene Footer-Komponente (wir werden sie etwas später schreiben), die automatisch zu jeder Seite unserer Anwendung hinzugefügt wird.



error.vue



Standardmäßig leitet Nuxt für jeden vom Server im http-Status zurückgegebenen Fehler zu layout / error.vue um und übergibt ein Objekt mit einer Beschreibung des Fehlers, der über einen Eingabeparameter namens error empfangen wurde.



Mal sehen, wie der Skriptabschnitt aussieht, um die Arbeit mit den empfangenen Fehlern zu vereinheitlichen:



<script lang="ts">  
import Vue from 'vue'  
  
type Error = {  
  statusCode: number  
  message: string  
}  
  
type ErrorText = {  
  title: string  
  subtitle: string  
}  
  
type ErrorTexts = {  
  [key: number]: ErrorText  
  default: ErrorText  
}  

export default Vue.extend({  
  name: 'ErrorPage',  
  
  props: {  
    error: {  
      type: Object as () => Error,  
      required: true,  
    },  
  },  
  
  data: () => ({  
    texts: {  
      404: {  
        title: '404. Page not found',  
        subtitle: 'Something went wrong, no such address exists',  
      },  
      default: {  
        title: 'Unknown error',  
        subtitle: 'Something went wrong, but we`ll try to figure out what`s wrong',  
      },  
    } as ErrorTexts,  
  }),  

  computed: {  
    errorText(): ErrorText {  
      const { statusCode } = this.error  
      return this.texts[statusCode] || this.texts.default  
    },  
  },  
})  
</script>
      
      





Was hier passiert:



1. Zuerst definieren wir die Typen, die in dieser Datei verwendet werden.



2. Im Datenobjekt erstellen wir ein Wörterbuch, das Nachrichten für alle Fehler enthält, für die wir eine eindeutige Nachricht und eine Standardnachricht für alle anderen anzeigen möchten.



3. In der berechneten Eigenschaft errorText prüfen wir, ob der empfangene Fehler im Wörterbuch enthalten ist. Wenn ein Fehler auftritt, geben wir eine Nachricht zurück. Wenn kein Fehler auftritt, geben Sie die Standardnachricht zurück.



In diesem Fall sieht unsere Vorlage folgendermaßen aus:



<template lang="pug">  
section.section  
  .content  
    .ep__container  
      section-header(  
        :title="errorText.title"  
        :subtitle="errorText.subtitle"  
      )  

      nuxt-link.ep__link(  
        class="primary"  
        to="/"  
      ) Home page  
</template>
      
      





Beachten Sie, dass wir hier die globalen Dienstprogrammklassen .section und .content verwenden, die wir zuvor in der Datei assets / styles / global / other.scss erstellt haben. Sie ermöglichen die Anzeige von Inhalten zentriert auf der Seite.



Hierbei wird die noch nicht erstellte Abschnittsüberschriftenkomponente verwendet, die jedoch in Zukunft eine universelle Komponente für die Anzeige von Überschriften sein wird. Wir werden es implementieren, wenn wir über Komponenten sprechen.



Das Layoutverzeichnis sieht folgendermaßen aus: Beginnen wir mit der Erstellung der Komponenten.



layouts/

-- default.vue

-- error.vue












Komponenten



Komponenten sind die Bausteine ​​unserer Anwendung. Beginnen wir mit den Komponenten, die wir oben bereits gesehen haben.



Um den Artikel nicht aufzublasen, werde ich die Stile der Komponenten nicht beschreiben. Sie finden sie im Repository dieser Anwendung.



SectionHeader Die

Überschriften in unserer Anwendung sind im gleichen Stil erstellt. Es ist daher logisch, eine Komponente zu verwenden, um sie anzuzeigen und die angezeigten Daten über die Eingabeparameter zu ändern.



Werfen wir einen Blick auf den Skriptabschnitt dieser Komponente:



<script lang="ts">  
import Vue from 'vue'  

export default Vue.extend({  
  name: 'SectionHeader',  

  props: {  
    title: {  
      type: String,  
      required: true,  
    },  
    subtitle: {  
      type: String,  
      default: '',  
    },  
  },  
})  
</script>
      
      





Nun wollen wir sehen, wie die Vorlage aussehen wird:



<template lang="pug">  
section.section  
  .content  
    h1.sh__title(  
      class="h1"  
    ) {{ title }}  

    p.sh__subtitle(  
      v-if="subtitle"  
      class="body2 regular"  
    ) {{ subtitle }}  
</template>
      
      





Wie wir sehen können, ist diese Komponente ein einfacher Wrapper für die angezeigten Daten und enthält keine Logik.



LinkToHome



Die einfachste Komponente in unserer Anwendung ist der Link über dem Titel, der von der ausgewählten Beitragsseite zur Startseite führt.



Diese Komponente ist sehr klein, daher werde ich den gesamten Code auf einmal (ohne Stile) angeben:



<template lang="pug">  
section.section  
  .content  
    nuxt-link.lth__link(  
      to="/"  
      class="primary"  
    )  
      img.lth__link-icon(  
        src="~/assets/icons/home.svg"  
        alt="icon-home"  
      )  
      | Home  
</template>  
  
<script lang="ts">  
import Vue from 'vue'  

export default Vue.extend({  
  name: 'LinkToHome',  
})  
</script> 
      
      





Beachten Sie, dass wir das Symbol home.svg aus dem Verzeichnis assets / icons anfordern. Zuerst müssen Sie dieses Verzeichnis erstellen und dort das gewünschte Symbol hinzufügen.



DbFooter



Die DbFooter- Komponente ist sehr einfach. Es enthält das Urheberrecht und einen Link zum Erstellen eines Briefes.

Die Anforderungen sind klar. Beginnen wir die Implementierung mit dem Skriptabschnitt:



<script lang="ts">  
import Vue from 'vue'  

export default Vue.extend({  
  name: 'DbFooter',  

  computed: {  
    copyright(): string {
      const year = new Date().getUTCFullYear()
      return ` ${year} · All rights reserved`
    },  
  },  
})  
</script>
      
      





In DbFooter haben wir nur eine berechnete Eigenschaft, die das aktuelle Jahr zurückgibt und mit einer bestimmten Zeichenfolge verknüpft ist. Schauen wir uns nun die Vorlage an:



<template lang="pug">  
section.section  
  .content  
    .footer  
      a.secondary(
        href="mailto:example@mail.com?subject=Nuxt blog"
      ) Contact us  
      p.footer__copyright(
        class="body3 regular"
      ) {{ copyright }}  
</template>
      
      





Wenn Sie auf den Link Kontakt klicken, öffnen wir den nativen Mail-Client und legen sofort den Betreff der Nachricht fest. Diese Lösung eignet sich für eine Demo unserer Anwendung. Im wirklichen Leben wäre es jedoch besser, ein Feedback-Formular zu implementieren, um Nachrichten direkt von der Site zu senden.



Postkarte



Die Postkarte ist einfach und unkompliziert.



<script lang="ts">  
import Vue from 'vue'  
import { Post } from '~/content/Post'  

export default Vue.extend({  
  name: 'PostCard',  

  props: {  
    post: {  
      type: Object as () => Post,  
      required: true,  
    },  
  },  

  computed: {  
    pageUrl(): string {  
      return `/post/${this.post.id}`  
    },  
  },  
})  
</script>
      
      





Im Skriptabschnitt definieren wir einen Eingabeparameter, post, der alle erforderlichen Informationen zum Beitrag enthält.



Wir implementieren auch die berechnete Eigenschaft pageUrl zur Verwendung in der Vorlage, die uns einen Link zur gewünschten Seite mit dem Beitrag zurückgibt.



Die Vorlage sieht folgendermaßen aus:



<template lang="pug">  
nuxt-link.pc(:to="pageUrl")  
  img.pc__img(  
    :src="getDynamicFile(post.img)"  
    :alt="`post-image-${post.id}`"  
  )  

  p.pc__title(class="body1 medium") {{ post.title }}  
  p.pc__subtitle(class="body3 regular") {{ post.desc }}  
</template>
      
      





Beachten Sie, dass das Stammelement der Vorlage nuxt-link ist. Dies geschieht, damit der Benutzer die Möglichkeit hat, den Beitrag mit der Maus in einem neuen Fenster zu öffnen.



Dies ist das erste Mal, dass das globale getDynamicFile-Mixin verwendet wird, das wir zuvor in diesem Artikel erstellt haben.



PostList



Die Hauptkomponente auf der Hauptseite besteht aus einem Postzähler oben und einer Liste der Posts selbst.



Der Skriptabschnitt für diese Komponente:



<script lang="ts">  
import Vue from 'vue'  
import posts from '~/content/posts'  

export default Vue.extend({  
  name: 'PostList',  
  
  data: () => ({  
    posts,  
  }),  
})  
</script>
      
      





Beachten Sie, dass wir das Array nach dem Importieren mit Posts zum Datenobjekt hinzufügen, damit die Vorlage in Zukunft auf diese Daten zugreifen kann.



Die Vorlage selbst sieht folgendermaßen aus:



<template lang="pug">  
section.section  
  .content  
    p.pl__count(class="body2 regular")  
      img.pl__count-icon(  
        src="~/assets/icons/list.svg"  
        alt="icon-list"  
      )  
      | Total {{ posts.length }} posts  

    .pl__items  
      post-card(  
        v-for="post in posts"  
        :key="post.id"  
        :post="post"  
      )  
</template>
      
      





Vergessen Sie nicht, das Symbol list.svg zum Verzeichnis Assets / Icons hinzuzufügen, damit alles ordnungsgemäß funktioniert.



PostFull



PostFull ist die Hauptkomponente auf einer separaten Post-Seite, die für die Anzeige des Post-Textes verantwortlich ist.



Für diese Komponente benötigen wir das Modul @ nuxtjs / markdownit , das für die Konvertierung von md in html verantwortlich ist.



Lassen Sie es uns installieren:



npm i @nuxtjs/markdownit
      
      





Fügen Sie dann @ nuxtjs / markdownit zum Modulabschnitt der Datei nuxt.config.js hinzu:



{
  modules:  [
    '@nuxtjs/markdownit',
  ],
}
      
      





Fein! Beginnen wir mit der Implementierung der Komponente. Wie immer aus dem Skriptabschnitt:



<script lang="ts">  
import Vue from 'vue'  
import { Post } from '~/content/Post'  
  
export default Vue.extend({  
  name: 'PostFull',  
  
  props: {  
    post: {  
      type: Object as () => Post,  
      required: true,  
    },  
  },  
})  
</script>
      
      





Im Skriptabschnitt definieren wir einen Eingabeparameter, post, der alle erforderlichen Informationen zum Beitrag enthält.



Fahren Sie mit der Vorlage fort:



<template lang="pug">  
section.section  
  .content  
    img.pf__image(  
      :src="getDynamicFile(post.img)"  
      :alt="`post-image-${post.id}`"  
    )  

    .pf__md(v-html="getDynamicFile(post.file).default")  
</template>
      
      





Wie Sie sehen können, werden mit unserem getDynamicFile-Mixin sowohl ein Bild als auch eine MD-Datei dynamisch abgerufen und gerendert.



Ich denke, Sie haben bemerkt, dass wir das Standardattribut v-html verwenden, um die Datei zu rendern, da @ nuxtjs / markdownit den Rest der Arbeit für uns erledigt. Unglaublich einfach!



Wir können den :: v-deep-Selektor verwenden, um auf die Stilanpassung unserer gerenderten .md-Datei zuzugreifen. Schauen Sie sich Github an, um zu sehen, wie diese Komponente implementiert ist.



In dieser Komponente setze ich nur Einzüge für Absätze, um das Prinzip der Anpassung zu zeigen. In einer realen Anwendung müssen Sie jedoch einen vollständigen Satz von Stilen für alle verwendeten und erforderlichen HTML-Elemente erstellen.



Seiten



Wenn alle Komponenten fertig sind, können wir mit dem Erstellen der Seiten beginnen.



Wie Sie wahrscheinlich bereits aus dem Design verstanden haben, besteht unsere Anwendung aus einer Hauptseite mit einer Liste aller Artikel und einer dynamischen Seite, auf der der ausgewählte Beitrag angezeigt wird.



Die Struktur des Seitenverzeichnisses: Alle Komponenten sind in sich geschlossen und ihre Zustände werden durch Eingabeparameter bestimmt, sodass unsere Seiten wie eine Liste von Komponenten aussehen, die in der erforderlichen Reihenfolge angegeben sind. Die Hauptseite sieht folgendermaßen aus:



pages/

-- index.vue

-- post/

---- _id.vue














<template lang="pug">  
.page  
  section-header(  
    title="Nuxt blog"  
    subtitle="The best blog you can find on the global internet"  
  )  

  post-list  
</template>  
  
<script lang="ts">  
import Vue from 'vue'  

export default Vue.extend({  
  name: 'HomePage',  
})  
</script>
      
      





Um die richtige Auffüllung festzulegen, haben wir die globale .page-Klasse verwendet, die wir zuvor in Assets / Styles / Global / Other.scss erstellt haben.



Eine einzelne Beitragsseite sieht etwas komplexer aus. Schauen wir uns zuerst den Skriptabschnitt an:



<script lang="ts">  
import Vue from 'vue'  
import { Post } from '~/content/Post'  
import posts from '~/content/posts'

export default Vue.extend({  
  validate({ params }) {  
    return /^\d+$/.test(params.id)  
  },  
  
  computed: {  
    currentId(): number {  
      return Number(this.$route.params.id)  
    },  
    currentPost(): Post | undefined {  
      return posts.find(({ id }) => id === this.currentId)  
    },  
  },  
})  
</script>
      
      





Wir sehen die Validierungsmethode. Diese Methode fehlt in Vue. Nuxt bietet uns die Möglichkeit, die vom Router empfangenen Parameter zu validieren. Validate wird jedes Mal aufgerufen, wenn Sie zu einer neuen Route navigieren. In diesem Fall überprüfen wir nur, ob die an uns übergebene ID eine Nummer ist. Wenn die Validierung fehlschlägt, wird der Benutzer zur Fehlerseite error.vue zurückgeführt.



Hier sind 2 berechnete Eigenschaften implementiert.



Schauen wir uns genauer an, was sie tun: 1. currentId - Diese Eigenschaft gibt uns die aktuelle Post-ID zurück (die aus den Router-Parametern erhalten wurde), nachdem sie zuvor in number konvertiert wurde.



2. currentPost gibt ein Objekt mit Informationen zum ausgewählten Beitrag aus dem allgemeinen Array aller Beiträge zurück.



Es scheint, dass sie es herausgefunden haben. Werfen wir einen Blick auf die Vorlage:



<template lang="pug">  
.page
  link-to-home  

  section-header(  
    :title="currentPost.title"  
  )  

  post-full(  
    :post="currentPost"  
  )
</template>
      
      





Der Stilabschnitt für diese Seite sowie für die Hauptseite fehlt.

Der Code für die Seiten auf Github .



Auf Hostman bereitstellen



Hurra! Unsere Bewerbung ist fast fertig. Es ist Zeit, mit der Bereitstellung zu beginnen.



Für diese Aufgabe verwende ich die Hostman- Cloud-Plattform , mit der Sie den Bereitstellungsprozess automatisieren können.



Unsere Anwendung wird eine statische Site sein, da ein kostenloser Plan für statische Sites in Hostman verfügbar ist.



Zum Veröffentlichen müssen wir auf der Plattformoberfläche auf die Schaltfläche Erstellen klicken, einen kostenlosen Plan auswählen und unser Github-Repository verbinden, wobei die erforderlichen Optionen für die Bereitstellung angegeben werden.



Unmittelbar danach wird die Veröffentlichung automatisch gestartet und eine kostenlose Domain in der Zone * .hostman.site mit dem installierten SSL-Zertifikat von Let's Encrypt erstellt.



Von nun an wird jeder neue Push an den ausgewählten Zweig (standardmäßig Master) verwendet, um eine neue Version der Anwendung bereitzustellen. Unglaublich einfach und bequem!



Fazit



Also was wir haben:





Wir haben versucht, in der Praxis zu zeigen, wie man mit dem Nuxt.js-Framework arbeitet. Es ist uns gelungen, eine einfache Anwendung von Anfang bis Ende zu erstellen, von der Erstellung eines UI-Kits bis zur Organisation einer Bereitstellung.



Wenn Sie alle Schritte in diesem Artikel ausgeführt haben, herzlichen Glückwunsch zum Erstellen Ihrer ersten Nuxt.js-Anwendung. War es schwierig? Wie arbeiten Sie mit diesem Framework? Wenn Sie Fragen oder Wünsche haben, zögern Sie nicht, in die Kommentare zu schreiben.



All Articles