#typescript #vue.js #vue-router
#typescript #vue.js #vue-маршрутизатор
Вопрос:
У меня есть API, который отвечает с помощью JSON, подобного этому:
{
"Thriller": "Thriller books",
"Biographical": "Biographical books",
"Romance": "Romance books"
}
Я хотел бы в конечном итоге получить маршруты, подобные этому:
http://example.com/thriller
http://example.com/biographical
http://example.com/romance
По сути, API должен определять, какие книги доступны для просмотра. После этого Books
компонент отобразит общие данные о конкретных типах книг. Я зашел так далеко с настройкой моего маршрутизатора:
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 говорит, что есть две проблемы с map()
: TS1005: comma expected
в конце строки и TS2349: Cannot invoke an expression - type String has no invocation signature
(грубо переведено).
Я не понимаю, что я должен делать. Может быть, есть лучший способ сделать то, что я пытаюсь? Я новичок в СПА-процедурах.
Комментарии:
1. что именно представляет собой сообщение об ошибке? и поступают ли данные из response.json() в виде массива при их регистрации?
2. @altruios Есть две ошибки:
TS1005: comma expected
в конце строки иTS2349: Cannot invoke an expression - type String has no invocation signature
(примерно переведено)
Ответ №1:
Если вы хотите использовать выбранный вами маршрут, это может быть более чистым способом генерации маршрутов.
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)
В противном случае я бы рекомендовал использовать динамическое сопоставление маршрутов для передачи идентификатора книги в компонент, а не выполнять блокирующий вызов API при загрузке страницы.
const router = new VueRouter({
routes: [
{ path: '/book/:shortname', component: Book }
]
})
Ответ №2:
а … смотрите выше на формат вашего json… причина, по которой map не работает, заключается в том, что это гигантский объект. и map работает только для массивов.
два решения… отформатируйте json в виде массива … например
{
"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" }
//]
или вместо map. используйте: Object.keys для получения массива из объекта, который затем можно перебирать с помощью map.
Object.keys(json).map(function(key, index) {
//your code here
});
Комментарии:
1. Я попробовал первое решение, и оно по-прежнему говорит, что в конце ожидалась запятая.
2. если вы выводите json — это буквально приведенный выше формат? если вы используете Object.keys(json).map(функция (ключ, индекс) { console.log(ключ «» индекс); }); каков результат?
3. неожиданный токен появляется для меня в codepen. ввод-вывод при копировании / вставке структуры json… когда я присваиваю его переменной, которая исчезает. вызывает ошибку: « { «Thriller»: «Книги о триллерах», «Biographical»: «Биографические книги», «Romance»: «Книги о романах» } « не вызывает ошибки « const books = { «Thriller»: «Книги о триллерах», «Biographical»: «Биографические книги», «Romance»: «Книги о романах» } «