Ich habe eine API, die mit einem JSON wie diesem antwortet:

{
    "Thriller": "Thriller books",
    "Biographical": "Biographical books",
    "Romance": "Romance books"
}

Am Ende möchte ich folgende Routen haben:

http://example.com/thriller
http://example.com/biographical
http://example.com/romance

Im Wesentlichen sollte die API vorgeben, welche Art von Büchern verfügbar sind. Anschließend zeigt die Komponente Books generische Daten zu bestimmten Buchtypen an. Mit meiner Routerkonfiguration bin ich so weit gekommen:

import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import Books from './views/Books.vue';

Vue.use(Router);

var books: Record<string, string> = await fetch('http://example.com/api/available-books')
    .then((response) => response.json())
    .then((data) => {
        return data;
    });


export default new Router({ 
    mode: 'history',
    base: process.env.BASE_URL,
    routes: books.map((shortname: string, fullname: string) => ({ component: Books, path: `/${shortname}`)),
});

TS linter sagt jedoch, dass es zwei Probleme mit map() gibt: TS1005: comma expected am Ende der Zeile und TS2349: Cannot invoke an expression - type String has no invocation signature (grob übersetzt).

Ich verstehe nicht, was ich tun soll. Vielleicht gibt es einen besseren Weg, um das zu tun, was ich versuche? Ich bin neu bei SPA.

1
xtl 18 Aug. 2020 im 20:51

2 Antworten

Beste Antwort

Wenn Sie die Route verwenden möchten, die Sie nehmen, ist dies möglicherweise eine sauberere Methode zum Generieren der Routen.

const books = {
    "Thriller": "Thriller books",
    "Biographical": "Biographical books",
    "Romance": "Romance books"
}

const output = Object.entries(books).map(book => {
  const [shortname, fullname] = book
  return { component: 'Books', path: `/${shortname.toLowerCase()}` } 
})

console.log(output)

Andernfalls würde ich empfehlen, dynamische Routenanpassung um die Buch-ID an die Komponente zu übergeben, anstatt beim Laden der Seite einen blockierenden API-Aufruf durchzuführen.

const router = new VueRouter({
  routes: [
    { path: '/book/:shortname', component: Book }
  ]
})
1
Chase Ingebritson 18 Aug. 2020 im 18:25

Ah ... schau oben auf das Format deines json ... der Grund, warum die Karte nicht funktioniert, ist, dass es ein riesiges Objekt ist. und map funktioniert nur für Arrays.

Zwei lösungen ... formatieren den json als array ... wie z

{
    "Thriller": "Thriller books",
    "Biographical": "Biographical books",
    "Romance": "Romance books"
}
const mappedToArray  = [];
for (const prop in json) {
    mappedToArray.push({[prop]:json[prop]});
}
console.log(mappedToArray) 
// output is:> Array [
//Object { Thriller: "Thriller books" },
// Object { Biographical: "Biographical books" },
// Object { Romance: "Romance books" }
//]

Oder anstelle von Karte. Verwenden Sie: Object.keys, um ein Array von einem Objekt abzurufen, das Sie dann mit map durchlaufen können.

Object.keys(json).map(function(key, index) {
//your code here
});
1
altruios 18 Aug. 2020 im 18:06