Wie man eine API mit Vuejs &Axios implementiert

Fallstudie:Hacker News API

Voraussetzung

  • Laptop mit Internetverbindung
  • Ein API-Client (z. B. Postman oder Insomnia)
  • Ein Code-Editor
  • Grundkenntnisse in Javascript, Vue.js, Axios, CSS, HTML
  • Konzentration

Dieses Tutorial wird Ihnen den Einstieg in die Hackernews-API erleichtern, Sie mit den 5 wichtigsten Endpunkten vertraut machen, die mit dieser API geliefert werden, erklären, wie Sie verschiedene Anfragen stellen können, und Ihnen beibringen, wie Sie einen einfachen erholsamen API-basierten Nachrichtenaggregator aufbauen API. Die Hacker News API wird von Hackernews in Partnerschaft mit Googles Firebase entwickelt, mit dem Ziel, die öffentlichen Hacker News-Daten nahezu in Echtzeit verfügbar zu machen. Dieses Tutorial behandelt die API-Entwicklung nicht im Detail, sondern zeigt Ihnen, wie Sie API-Endpunkte effektiv testen und verwenden.

So folgen Sie diesem Tutorial

Dieses Tutorial ist wie folgt in 3 verschiedene Abschnitte unterteilt:

  • Erste Schritte
  • API-Anfragen an die verfügbaren Endpunkte stellen
  • Die Hacker News Reader-App

Um das Beste aus diesem Tutorial herauszuholen, empfehle ich Ihnen, diesem Tutorial einen Abschnitt nach dem anderen zu folgen, da jeder Abschnitt nahtlos in den anderen übergeht. Wenn Sie bereit sind, neue Techniken zu erlernen, machen Sie mit und bringen Sie den Ball ins Rollen.

Erste Schritte

Bevor wir beginnen, gibt Ihnen eine Tour durch die Endpunkte, die mit dieser API geliefert werden, einen Eindruck davon, wie die API entworfen, strukturiert und bereitgestellt wird. Die Hackernews-API verfügt über 5 Hauptendpunkte, die zum Sammeln von Nachrichten, Jobs, Poles und Kommentaren auf der Hackernews-Website verwendet werden. Für grundlegende Informationen und um zu erklären, wie einfach die API ist, werde ich die 5 Endpunkte erläutern, indem ich die unten aufgeführten Anfragen mit Postman an die Endpunkte sende:

  • Artikel
  • Nutzer
  • Top-Storys
  • Max. Element-ID
  • Geänderte Elemente und Profile

Die Basis-URL für die Endpunkte lautet http://hacker-news.firebaseio.com/Items/v0/item/.json

Der Item-Endpunkt gibt alle Link-Posts, Kommentare, Jobs, Ask HN-Posts und Umfragen zurück, die alle als „Items“ kategorisiert sind. Auf sie kann an diesem Endpunkt über ihre eindeutige ID zugegriffen werden. Lassen Sie uns gemeinsam den Endpunkt „items“ testen, öffnen Sie Postman, legen Sie Ihre Anfrage-URL wie folgt fest:https://hacker-news.firebaseio.com/v0/item/8861.json, wählen Sie „GET“ als Ihren Anfragetyp und drücken Sie auf „Senden“. Sie sollten das gleiche Ergebnis wie im folgenden Screenshot erhalten:

Sie haben bemerkt, dass ich die „Integrid“ durch „/v0/item/8861.json/“ als eindeutige Kennung für dieses bestimmte Element ersetzt habe. Hinweis:Ein Element kann entweder eine Geschichte, ein Kommentar, ein Job, eine Frage usw. sein. Sie können auch den Baum durchqueren und noch tiefer vordringen. Wir werden mehr über das Traversieren im Abschnitt Hackernews Reader App üben.

Benutzer /v0/user/<userid>.json

Jeder Benutzer wird durch Groß- und Kleinschreibung eindeutig identifiziert und lebt unter „/v0/user/“. Dieser Endpunkt zeigt nur Benutzer an, die öffentliche Aktivitäten (z. B. Kommentare oder Beitragsübermittlungen) auf der Website haben. Der folgende Screenshot ist das Ergebnis einer „GET“-Anforderung an die URL https://hacker-news.firebaseio.com/v0/user/john.json.

Sie haben bemerkt, dass die eindeutige Kennung dieses Mal „John“ ist. Was ist, wenn Sie alle Kommentare erhalten möchten, die der Benutzer bisher gemacht hat? Die ideale Lösung wäre die Verwendung des „submitted“-Arrays, um auf Elemente zuzugreifen, die der Benutzer veröffentlicht hat. Denken Sie daran, dass der Endpunkt nur einen Benutzer mit Aktivität zurückgibt. Wir werden im nächsten Abschnitt näher darauf eingehen.

Schlagzeilen /v0/topstories.json

Dieser Endpunkt gibt die Element-IDs für die Top-500-Storys auf Hackernews zurück. Sie können diesen Endpunkt verwenden, um auf die IDs der Top-Elemente auf der Website zuzugreifen. Die neusten Meldungen sind unter „/v0/topstories“ (enthält auch Jobs) und „/v0/newstories“ abrufbar. Auf die besten Geschichten kann auch unter „/v0/beststories“ zugegriffen werden. Der folgende Screenshot ist das Ergebnis einer „GET“-Anfrage an https://hacker-news.firebaseio.com/v0/topstories.json.

Mit diesem Endpunkt können Sie noch mehr erreichen, wir werden diesen API-Endpunkt im Abschnitt Hackernews Reader App verwenden.

Max. Element-ID

Dieser Endpunkt gibt die aktuell größte Element-ID /v0/maxitem zurück . Dies könnte der richtige Ansatz sein, um rückwärts zu raten, um alle auf der API verfügbaren Elemente zu entdecken.

Geänderte Elemente und Profile

Diese API gibt eine Liste von Elementen und Profilen zurück, die sich in Echtzeit geändert haben. Vielen Dank an Firebase für diese großartige Funktion, die Artikel- und Profiländerungen befinden sich unter „/v0/updates“. Dieser Endpunkt kann sehr hilfreich sein, wenn Sie Änderungen in Echtzeit in Ihrer Anwendung nachverfolgen möchten.

Die Hacker News Reader-App

Wenn Sie dieses Tutorial bis zu diesem Punkt befolgt haben, herzlichen Glückwunsch, Sie sind mit dem Wissen und Verständnis ausgestattet, das zum Erstellen der Hackernews Reader App erforderlich ist. Beginnen wir damit, dass wir eine Anfrage stellen, um 50 Top-Storys abzurufen und sie in absteigender Reihenfolge zu ordnen und sie nach Stimmen sortieren zu lassen. Dies wird der Baustein für unsere Reader-App sein. Wir werden Javascript verwenden, um die Logik für diese Anwendung, Vue.js, zu handhaben, um das Front-End und Axios zum Senden von Anforderungen an die jeweiligen Endpunkte zu erstellen.

Was ist Vue.js?

Vue ist ein fortschrittliches Framework zum Erstellen von Benutzeroberflächen. Vue ist von Grund auf so konzipiert, dass es schrittweise angepasst werden kann. Die Kernbibliothek konzentriert sich nur auf die Ansichtsebene und ist einfach zu übernehmen und in andere Bibliotheken oder bestehende Projekte zu integrieren. Andererseits ist Vue auch perfekt in der Lage, anspruchsvolle Single-Page-Anwendungen zu betreiben, wenn es in Kombination mit modernen Werkzeugen und unterstützenden Bibliotheken verwendet wird. Ich habe vue.js für dieses Tutorial aus keinem anderen Grund als seiner Einfachheit und seiner einfachen Handhabung ausgewählt. Dieser Grund ist nicht auf das beschränkt, was Sie mit vue.js erreichen können, Sie können diese Anwendung auch mit anderen Frontend-Frameworks wie React.js oder Angular erstellen. Hier können Sie die Dokumentation lesen und mit vue.js beginnen.

Was ist Axios?

Axios ist ein Promise-basierter HTTP-Client für den Browser und node.js. Axios ist eine Javascript-Bibliothek, die ziemlich einfach in jedes Front-End-Framework oder jede vorhandene Anwendung, die in Javascript geschrieben ist, integriert werden kann. Wir werden Axios nicht innerhalb von vue.js verwenden, da ich nicht möchte, dass wir innerhalb unserer Komponenten mehrere Anfragen stellen. Wir werden einen „Story-Service“ erstellen, der alle Anfragen an unsere Endpunkte verarbeitet und die Ausgabe über Requisiten innerhalb von Komponenten weiterleitet. Klicken Sie hier, um Anweisungen zur Installation von Axios über den node.js-Paketmanager (npm) zu lesen.

Einrichtung und Installation:

  • Erstellen Sie eine neue Anwendung
  • Axios installieren
  • Erstellen Sie einen Dienstordner

Beginnen wir, navigieren Sie zu Ihrem Arbeitsverzeichnis und kopieren Sie den folgenden Code und fügen Sie ihn auf Ihrem Terminal ein, um eine vue.js-Anwendung zu erstellen. Stellen Sie sicher, dass Sie vue-cli haben auf Ihrem Rechner installiert. Folgen Sie den Anweisungen zur Installation und den ersten Schritten mit vue-cli hier.

$ vue create vue-hackernews

Wählen Sie Ihre bevorzugten Add-Ons aus und geben Sie den folgenden Code ein:

    $ cd vue-hackernews
    $ npm run serve

Wenn Sie alles richtig eingerichtet haben, sollten Sie das folgende Ergebnis haben:

    App running at:
    - Local: http://localhost:8081/
    - Network: http://172.20.10.3:8081/

Halten Sie die Befehlstaste gedrückt und klicken Sie auf den lokalen Link, um die Web-App in Ihrem Browser anzuzeigen (cmd + Klick). Bravo!! Sie sollten das folgende Ergebnis erhalten:

Axios installieren:

Kopieren Sie den folgenden Code und fügen Sie ihn auf Ihrem Terminal ein, um Axios zu installieren:

$ npm i axios

Nachdem Sie nun die Barebones der Reader-App generiert haben, erstellen Sie einen neuen Ordner im Ordner „src“ mit dem Namen seiner Dienste. Lassen Sie uns als Nächstes unsere Ordnerstruktur durchgehen und einige Inhalte entfernen, die wir nicht benötigen. Unten ist ein durchlaufender Baum, wie unsere Ordnerstruktur aussieht.

├── vue-hackernews
├── public
   ├── style.css
├── src
   ├── assets
      ├── css
         ├── main.css
      ├── bk-sale.png
├── componets
    ├── singleStory.vue
    ├── storyItem.vue
├── router
    ├── index.js
├── services
    ├── storyService.js
├── views
    ├── home.vue
    ├── singleStory.vue
├── App.vue
├── main.js

Erklärte Ordnerstruktur:

Die Hackernews Reader App ist eine einseitige Anwendung, die mit dem Ziel entwickelt wurde, zu veranschaulichen, wie Sie eine Anwendung auf der Grundlage der Hackernews-API erstellen können. Wenn Sie veu-cli zum Generieren der Anwendung verwendet haben, sollten Sie eine ähnliche Ordnerstruktur wie oben haben. Der Ordner „/src“ ist der Einstiegspunkt für unsere Anwendung, er enthält alle Ordner und relevanten Dateien für unsere Web-App. Der Ordner „/asset“ enthält das Stylesheet und Bilder für die Anwendung, der Ordner „/components“ enthält alle Komponenten für die Anwendung, der Ordner „/router“ enthält „index.js“, ein Skript, das für das Routing in der Anwendung verantwortlich ist. Der Ordner „/services“ ist ein von mir erstellter benutzerdefinierter Ordner, er enthält alle Dienste für die Anwendung, der Ordner „/view“ enthält alle Ansichten für die Anwendung (z. B.:home.vue und singleStory.vue), die „App. vue“ rendert alle Ansichten/Routen in der Anwendung, schließlich ist die Datei „main.js“ ein Skript, das die Komponente „App.vue“ als übergeordnete Komponente für die gesamte Anwendung rendert, indem sie an die vue.js-Engine übergeben wird, die eingefügt wird -wandeln Sie es in 'HTML' um, das auf Webbrowsern lesbar ist.

Aufbau des „Story-Service“

Navigieren Sie in den Dienstordner, erstellen Sie eine neue Datei mit dem Namen „storyService.js“, kopieren Sie den folgenden Code und fügen Sie ihn ein:

import axios from 'axios';
    const baseUrl = 'https://hacker-news.firebaseio.com/v0';
    /* 
     *  Fetch list of the top 50 stories
     *  returns stories[].
    */
    export async function getTopStories() {
        let stories = [];
        const response = await axios.get(`${baseUrl}/topstories.json`, {
            params: {
                limitToFirst: '50',
            }
        });
        stories = response.data;
        return stories;
    }
    /* 
     *  Fetch items based on 'ids' from getTopStories()
     *  returns items[].
    */
     export async function storiesWithItems(){
         let items = [];
         getTopStories().then(stories => {
              stories.forEach(id => {
               axios.get(`${baseUrl}/item/${id}.json`).then( res => {
                items.push(res.data);
               });
              });   
         });
         return items;
     }
    /* 
     *  Makes request based on the 'id' param
     *  returns response[].
    */
     export async function getSingleItem(id){
        let response;
        response = await axios.get(`${baseUrl}/item/${id}.json`);
        return response.data;
    };

    /* 
     *  Makes request based on the 'id' passed to the
     *  getSingleItem(<id>), loops through kids[];
     *  returns comments[].
    */
    export async function getSingleStoryComments(id) {
        let comments = [];
        getSingleItem(id).then(res => {
            res.kids.forEach(comment => {
                 axios.get(`${baseUrl}/item/${comment}.json`).then(res => {
                     comments.push(res.data);
                 });
            })
        });
        return comments;
    }
    /* 
     *  Sorts the result based on the property score;
     *  returns a sorted array.
    */
    export function sortByScore(a, b){
        if (a.score < b.score) {
            // a comes before b in the sorted order 
            return -1;
        }else if(a.score > b.score){
            // a comes before b in the sorted order
            return 1;
        }else{
            // a and b are the same
            return 0
        }
    }

Das Konzept dieser Dienste kann mit einer Truppe von Soldaten verglichen werden, die gemeinsam für eine Sache kämpfen. Wir hätten genauso gut die gesamte App mit ein oder zwei Funktionen bauen können, aber wir müssen unsere App wiederverwendbar, wartbar und auch leicht lesbar und verständlich machen.

getTopStories():

Ich begann mit dem Importieren von axios , dann habe ich eine Konstante deklariert, um den baseurl zu halten für unsere API die getTopStories() Die Funktion stellt eine asynchrone Anfrage an den Endpunkt „topstories.json“ und gibt 50 Geschichten zurück, die nach Stimmen in absteigender Reihenfolge geordnet sind. Sie haben bemerkt, dass ich in den Parametern „Object“ die Parameter „orderBy:votes“ und „limitToFirst:50“ einschließe, diese Parameter werden beim Senden der Anfrage als Header durch die URL geleitet und vom Endpunkt zum Abrufen der Daten empfangen. Weitere Informationen zum Abrufen von Daten in Firebase finden Sie hier.

Die getTopStroies() Funktion gibt nur ids zurück für die ersten 50 Top-Storys. Um auf Details der Geschichten zuzugreifen, müssen wir eine weitere iterative Anfrage stellen, basierend auf dem Ergebnis, das wir zu /item/${id}.json erhalten Endpunkt. Wir hätten das auch innerhalb dieser Funktion erledigen können, aber wir müssen die Wartbarkeit im Auge behalten, also werden wir das einer anderen Funktion überlassen.

StoriesWithItems():

Diese Funktion basiert auf dem getTopStories() Funktion zum Abrufen von Geschichten, die mit den zurückgegebenen „IDs“ verknüpft sind. Es gibt viele Möglichkeiten, wie Sie diese Aufgabe erledigen können. Ich habe mich entschieden, eine neue Anfrage an /item/${id}.json zu stellen Endpunkt durch Iterieren aller „ids“, die von der Funktion „getTopStroies()“ zurückgegeben werden. Jedes in der Schleife gefundene Element wird in das Array „item“ geschoben, das zurückgegeben wird, wenn die Schleife endet.

getSingleItem(id):

Die getSingleItem() sendet eine Anfrage an /item/${id}.json Endpunkt und gibt ein einzelnes Element basierend auf itemid zurück dazu übergegangen. Diese Funktion wird auch vom getSingleStoryComments(id) verwendet zum Abrufen von Kommentaren, die mit dem aktuellen item verknüpft sind .

getSingleStoryComments(id):

Diese Funktion ähnelt der Funktion storiesWithItem(), ihr Hauptzweck besteht darin, alle Kommentare zurückzugeben, die einem einzelnen item zugeordnet sind durch Iterieren seines kids -Array und eine Anfrage an /item/${id}.json stellen Endpunkt mit jedem der kid . Es ist erstaunlich, wie die Hackernews-API strukturiert ist, Kommentare sind Elemente mit dem „Typ:Kommentar“ und sind direkte Kinder des Story-Objekts, auf das über den kids zugegriffen werden kann Array.

Sortieren der Artikel nach der höchsten Bewertung:

sortByScore(a, b):

Der sortByScore() ist eine Callback-Funktion, die die Sortierreihenfolge für unseren items definiert , wird die Funktion oft als Parameter an die Javascript-Funktion sort übergeben. In unserem Fall erfolgt die Sortierung nach item mit der höchsten Stimme. Es vergleicht das erste Element (a) mit dem nächsten (b) im Objekt eines Arrays basierend auf der höchsten Punktzahl, reduziert seine Indexnummer und schiebt es jedes Mal um einen Schritt nach vorne, wenn keine Übereinstimmung mit vis-vis gefunden wird. Lesen Sie hier mehr über die Sortierfunktion.

Erstellen der Komponenten

Nachdem Sie nun mit dem Erstellen des Story-Dienstes fertig sind, erstellen wir die für unsere Anwendung erforderlichen Komponenten. Navigieren Sie zum Komponentenordner und erstellen Sie singleitem.vue und singleStoryItem.vue Komponenten.

Kopieren Sie den folgenden Code und fügen Sie ihn ein, um signgleItem.vue zu erstellen:

<template>
    <div class="story">
    <span class="score">{{ item.title | url }}</span>
    <router-link  :to="{ path: '/story/' + item.id }"
    >{{ item.title }}
    </router-link><br />
    <span class="own-url">{{ item.url | host }}</span><br />
    <span class="meta">
    by: <span class="author">@{{ item.by }} </span> | Time: {{ item.time }} Ago | {{
    item.descendants }} comments
    </span>
    </div>
    </template>
    <script>
    export default {
    name: 'storItem',
    props:{
    item: {
    type: Object,
    required: true,
    },
    index:{
    type: Number,
    required: true,
    }
    },
    filters:{
    url: function(str){
    return str.substring(0, 2).toUpperCase();
    }
    }
    }
    </script>
    <style scoped>
    .item {
    border-radius: 5px;
    padding: 20px;
    background: white;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: relative;
    }
    .salepill {
    background: rgb(232, 35, 25);
    color: white;
    font-family: 'Barlow', sans-serif;
    position: absolute;
    right: 30px;
    top: 60px;
    padding: 2px 10px 4px;
    text-transform: uppercase;
    font-size: 13px;
    font-weight: 700;
    border-radius: 1000px;
    }
    .author{
    color: #FFF;
    border-radius: 10px;
    background: teal;
    }
    .own-url{
    font-size: .8rem;
    color: black;
    }
    .story {
    background-color: #fff;
    padding: 20px 30px 20px 80px;
    border-bottom: 1px solid #eee;
    position: relative;
    line-height: 20px;
    }
    .score {
    color: #f60;
    font-size: 1.1em;
    font-weight: 700;
    position: absolute;
    top: 50%;
    left: 0;
    width: 80px;
    text-align: center;
    margin-top: -10px;
    }
    .story a {
    color: #34495e;
    font-weight: 600;
    text-decoration: none;
    }
    .story a span {
    font-size: 0.85em;
    margin-left: 10px;
    color: #828282;
    }
    .story .meta {
    font-size: 0.85em;
    color: #828282;
    }
    </style>

Diese Komponente wurde im Hinblick auf Flexibilität erstellt, sie akzeptiert „Element“ und „Index“ als Requisiten. Props in vue.js werden verwendet, um Daten von einer Komponente zur anderen zu übergeben. Wir werden nicht wirklich tief in veu.js eintauchen, da dies den Rahmen dieses Tutorials sprengen würde.

Der singleStoryItem.vue Komponente:

Kopieren Sie den folgenden Code und fügen Sie ihn ein, um die Komponente zu erstellen.

<template>
    <div class="comment-container">
    <h2 class="story-title">{{ item.title }}</h2>
    <p class="score">Votes: {{ item.score }}</p>
    <p class="author-url">{{ item.url }}</p>
    <div v-for="(comment, index) in comments" :key="index">
    <div class="comment-wrap">
    <div class="comment-block">
    <p class="comment-text">{{ comment.text }}</p>
    <div class="bottom-comment">
    <div class="comment-author">{{ comment.by }}</div>
    <div class="comment-date">{{ comment.time }}</div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </template>
    <script>
    export default {
    name: "single-story",
    props:{
    item: {
    type: Object,
    required: true,
    },
    comments:{
    type: Array,
    required: true,
    }
    }
    }
    </script>
    <style scoped>
    .comment-container{
    width: 60%;
    margin: 0 auto;
    color: #000;
    }
    .story-title, .score, .author-url{
    padding: 1rem;
    }
    .story-title{
    text-transform: uppercase;
    font-weight: 900;
    }
    .author-url{
    font-size: .8rem;
    font-weight: 900;
    }
    .score{
    font-weight: 900;
    }
    .comment-wrap {
    margin-bottom: 1.25rem;
    display: table;
    width: 100%;
    min-height: 5.3125rem;
    }
    .photo {
    padding-top: 0.625rem;
    display: table-cell;
    width: 3.5rem;
    }
    .photo .avatar {
    height: 2.25rem;
    width: 2.25rem;
    border-radius: 50%;
    background-size: contain;
    }
    .comment-block {
    padding: 1rem;
    background-color: #fff;
    display: table-cell;
    vertical-align: top;
    border-radius: 0.1875rem;
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08);
    }
    .comment-block textarea {
    width: 100%;
    resize: none;
    }
    .comment-text {
    margin-bottom: 1.25rem;
    }
    .bottom-comment {
    color: #acb4c2;
    font-size: 0.875rem;
    }
    .comment-date {
    float: left;
    }
    .comment-actions {
    float: right;
    }
    .comment-actions li {
    display: inline;
    margin: -2px;
    cursor: pointer;
    }
    .comment-actions li.complain {
    padding-right: 0.75rem;
    border-right: 1px solid #e1e5eb;
    }
    .comment-actions li.reply {
    padding-left: 0.75rem;
    padding-right: 0.125rem;
    }
    .comment-actions li:hover {
    color: #0095ff;
    }
    </style>

Der singleStoryItem.vue Komponente ähnelt singleItem.vue der Unterschied ist, dass ich den index entfernt habe prop und fügte den comment hinzu Prop mit dem ‘Typ:Array’. Im nächsten Abschnitt werden Sie verstehen, warum ich mich entschieden habe, diese Komponente auf diese Weise zu erstellen.

Erstellen der Home- und SingleStory-Ansicht:
Startansicht:

Kopieren Sie den folgenden Code und fügen Sie ihn ein, um die Startansicht zu erstellen:

<template>
    <div class="home">
    <div class="banner">
    <h2 class="header">Hacker News API Implementation</h2>
    <img class="home-img" src="../assets/bk-sale.png">
    </div>
    <storyItem v-for="(story, index) in stories" :key="index" :item="story" :index="index"></storyItem>
    </div>
    </template>
    <script>
    // @ is an alias to /src
    import storyItem from '@/components/storyItem.vue';
    import { storiesWithItems, sortByScore } from '../services/storyService';
    export default {
    name: 'Home',
    components: {
    storyItem
    },
    data(){
    return{
    stories: [],
    }
    },
    created(){
    storiesWithItems().then(res => {
    this.stories = res.sort(sortByScore);
    });
    },
    }
    </script>
    <style scoped>
    .content {
    /*no grid support*/
    float: left;
    width: 79.7872%;
    /* grid */
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    padding: 0 !important;
    margin: 30px;
    }
    .banner{
    display: flex;
    flex-direction: row;
    align-content:space-between;
    background-color: teal;
    }
    .header{
    font-weight: 900;
    margin: 4rem;
    width: 60%;
    }
    .home-img{
    width: 40%;
    }
    </style>

Sie haben bemerkt, dass ich den singleItem importiert habe Komponente als untergeordnete Komponente und den storiesWithItem() Funktion aus dem storyService in die Home-Ansicht. Die an die Requisiten gelieferten Daten sind die Antwort von storiesWithItems() Funktion. Dies ist einer der Gründe, warum es klug war, unsere App aufweckbar zu machen, sodass wir am Ende nur eine Anfrage mit dem „erstellten Block“ gestellt haben, um diese Aufgabe auszuführen.

SingleStory-Ansicht:

Kopieren Sie den folgenden Code und fügen Sie ihn ein, um die Startansicht zu erstellen:

<template>
    <div class="home">
    <div class="banner">
    <h2 class="header">Hacker News API Implementation</h2>
    <img class="home-img" src="../assets/bk-sale.png">
    </div>
    <div class="container">
    <singleStoryItem :item="story" :comments="comments"></singleStoryItem>
    </div>
    </div>
    </template>
    <script>
    // @ is an alias to /src
    import singleStoryItem from '@/components/singleStoryItem.vue';
    import {getSingleItem, getSingleStoryComments } from '../services/storyService';
    export default {
    name: 'Home',
    components: {
    singleStoryItem
    },
    data(){
    return{
    story: {},
    comments: [],
    }
    },
    created(){
    getSingleItem(this.$route.params.id).then(res => {
    this.story = res;
    });
    getSingleStoryComments(this.$route.params.id).then(res => {
    this.comments = res;
    })
    },
    }
    </script>
    <style scoped>
    .content {
    /*no grid support*/
    float: left;
    width: 79.7872%;
    /* grid */
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    padding: 0 !important;
    margin: 30px;
    }
    .banner{
    display: flex;
    flex-direction: row;
    align-content:space-between;
    background-color: teal;
    }
    .header{
    font-weight: 900;
    margin: 4rem;
    width: 60%;
    }
    .home-img{
    width: 40%;
    }
    </style>

Die Ausgabe für den obigen Code ergibt den folgenden Screenshot:

Aktualisieren Sie abschließend „App.vue“, „router.js“ und „main.css“ wie folgt:

router.js:

import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import Single from '../views/SingleStory.vue';
    Vue.use(VueRouter)
    const routes = [
    {
    path: '/',
    name: 'Home',
    component: Home
    },
    {
    path: '/story/:id',
    name: 'single',
    component: Single,
    }
    ]
    const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
    })
    export default router

Sie haben bemerkt, dass der Story-Pfad einen Parameter „/story/:id“ hat, der an getSingleStoryComments(id) übergeben wird, um das aktuelle „item“ abzurufen, das der „id“ zugeordnet ist. Dies ist dank des vue.js-Objekts „$router.params“ wirklich hilfreich.

App.vue:

<template>
    <div id="app">
    <div id="nav">
    <router-link to="/"> Home
    </router-link>
    </div>
    <router-view/>
    </div>
    </template>
    <style>
    @import url('./assets/css/main.css');
    </style>

main.css:

/* ---- global styles ---- */
    body,
    html {
      padding: 0;
      margin: 0;
      background: #f3f3f3;
      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;
      font-family: Avenir, Helvetica, Arial, sans-serif;
    }
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      color: white;
    }
    h1,
    h2,
    h3,
    h4 {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      font-weight: 700;
    }
    p,
    li {
      font-family: 'Barlow', sans-serif;
    }
    #nav{
      background-color: teal;
      height: 40px;
    }
    #nav a {
      text-decoration: none;
      color: #ffffff;
      margin: .7rem;
      margin-top: .8rem;
    }


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

    .container {
      padding-right: 15px;
      padding-left: 15px;
      margin-right: auto;
      margin-left: auto;
    }

Die vollständige Codebasis für dieses Tutorial ist hier verfügbar.

Einschränkung:

Obwohl ich die Einfachheit der API schätze, habe ich herausgefunden, dass die API viele Netzwerkanfragen erfordert, um eine einzelne Aufgabe zu erfüllen, was meiner Meinung nach in Anbetracht der Laufzeit nicht richtig ist. Um beispielsweise alle Kommentare abzurufen, die mit einem bestimmten „Element“ verknüpft sind, müssen iterative Anfragen an den „Element“-Endpunkt gestellt werden. Stellen Sie sich ein Element mit bis zu 300 Kommentaren vor, das Laden dauert sehr lange. P>

Die Hackernews-API ist schreibgeschützt, was die Art der Anfrage, die Sie stellen können, auf schreibgeschützt beschränkt. Trotz der Einfachheit der API ist sie in manchen Dingen gut und in anderen nicht.

Fazit:

Es gibt viele Ansätze, die Sie nutzen können, um diese API zu implementieren, insbesondere um die Laufzeit zu verbessern. Sie können die Artikelobjekte im Browser zwischenspeichern und müssen nur eine Netzwerkanfrage stellen, um die aktuellen Top 50 „IDs“ zu erhalten, dann nur diejenigen anfordern, die derzeit nicht zwischengespeichert sind, und dann die „Elemente“ der Reihenfolge nach anordnen die Top-50-Liste. Fühlen Sie sich frei, tief in diese API einzutauchen und andere Konzepte zu erkunden. Ich würde gerne von Ihnen hören, bitte hinterlassen Sie einen Kommentar unten. Danke fürs Lesen.