如何在 VueJS 的搜索栏中实现 API?
How do I implement APIs in a search bar on VueJS?
我正在做一个大学项目,我一直在尝试实现一个搜索栏,该搜索栏从 API (https://api.rawg.io/api/games) 中获取游戏名称,并在点击游戏后重定向用户访问包含特定游戏的页面 URL。现在,我希望我至少能够完成第一部分。
我创建了一个 searchbar.vue 组件并从官方 Vuetify 库中复制粘贴了代码:
(https://github.com/vuetifyjs/vuetify/blob/master/packages/docs/src/examples/autocompletes/simple/api.vue)
但是,如果我将 API 从他们作为示例提供的那个更改为我需要的那个 (rawg),它就不再起作用了,我不确定为什么。
如何让我的搜索栏正常工作?
我正在为我目前工作的 codesandbox 提供 link,以备不时之需:
(https://codesandbox.io/s/searchbar-mtjr2?file=/src/components/searchbar.vue)
如果需要,我会尽力提供有关该问题的更多信息。
提前非常感谢您考虑这个 post。
我相信搜索栏的所有问题都已解决:Demo here
我在代码中添加了注释,因此应该清楚它是如何工作的。
在searchbar.vue中:
<template>
<v-autocomplete
clearable
:loading="isLoading"
:items="games"
:search-input.sync="search"
hide-details
item-text="name"
item-value="id"
label="Search for a Game..."
solo-inverted
></v-autocomplete>
</template>
<script>
import _ from "lodash";
export default {
data: () => ({
games: [], // this is where all the game data will be stored
isLoading: true, // variable to determine if the results are still being fetched from the API
search: null // this is where the query will be stored
}),
methods: {
getGames(params = "") {
// this function will fetch game data from https://api.rawg.io/api/games with whatever api parameters you pass to the parameter `params`
this.axios
.get("https://api.rawg.io/api/games" + params)
.then(resp => {
// fetch data
let tempGames = [...this.games.slice(0), ...resp.data.results]; //copy of this.games + new data
this.games = _.uniqBy(tempGames, "id"); // remove any duplicates
this.isLoading = false; // now that the data is in the array `games`, we can set isLoading to false
})
.catch(e => {
// code to run if there was an error
console.error(e); // display error message
});
},
searchGames(query) {
// this function will call getGames() with the search query formatted as an API parameter (?search=YOUR_QUERY)
let searchQuery = encodeURI("?search=" + query); // URI encode the query so it is able to be fetched properly
this.getGames(searchQuery);
}
},
watch: {
search: _.debounce(function(query) {
// debounce with a a value of 250 will allow this function to be every 250 milliseconds at most. So if the user is typing continually, it won't run until the user stops.
this.searchGames(query);
}, 250)
},
created() {
this.getGames(); // load the first 20 games initally
}
};
</script>
这将:
- 加载前 20 个游戏
- 当您输入查询并停止输入时,它将执行对
https://api.rawg.io/api/games?search=YOUR_QUERY
的请求,并将结果添加到 games
数组。 (所以每次你搜索一些东西,saved games 数组都会增加。这意味着如果你搜索同一个游戏两次,虽然它仍然会用 https://api.rawg.io/api/games?search=YOUR_QUERY
在线搜索,但游戏已经在 games 数组中了从第一次开始,所以它会立即加载。)
v-autocomplete
过滤并显示结果。
此方法在更快的连接上效果更好,因为结果加载速度更快。因此,如果您的连接速度较慢,则加载结果可能需要一些时间。不幸的是,这是无法解决的问题(虽然您可以预先加载大量数据,但不能保证您加载的是用户将搜索的内容)
导航栏的图形问题已通过将 App.vue 中的父 <div>
更改为 <v-app>
解决,如下所示:
之前:
<template>
<div id="app">
<nav-bar></nav-bar>
...
</div>
</template>
之后:
<template>
<v-app id="app">
<nav-bar></nav-bar>
...
</v-app>
</template>
我还添加了 lodash
作为去抖动(等待用户停止输入)和删除重复项的依赖项。
这是我正在处理的 codepen。
如果您还有其他问题,请告诉我。
我正在做一个大学项目,我一直在尝试实现一个搜索栏,该搜索栏从 API (https://api.rawg.io/api/games) 中获取游戏名称,并在点击游戏后重定向用户访问包含特定游戏的页面 URL。现在,我希望我至少能够完成第一部分。
我创建了一个 searchbar.vue 组件并从官方 Vuetify 库中复制粘贴了代码: (https://github.com/vuetifyjs/vuetify/blob/master/packages/docs/src/examples/autocompletes/simple/api.vue)
但是,如果我将 API 从他们作为示例提供的那个更改为我需要的那个 (rawg),它就不再起作用了,我不确定为什么。
如何让我的搜索栏正常工作?
我正在为我目前工作的 codesandbox 提供 link,以备不时之需: (https://codesandbox.io/s/searchbar-mtjr2?file=/src/components/searchbar.vue)
如果需要,我会尽力提供有关该问题的更多信息。
提前非常感谢您考虑这个 post。
我相信搜索栏的所有问题都已解决:Demo here
我在代码中添加了注释,因此应该清楚它是如何工作的。
在searchbar.vue中:
<template>
<v-autocomplete
clearable
:loading="isLoading"
:items="games"
:search-input.sync="search"
hide-details
item-text="name"
item-value="id"
label="Search for a Game..."
solo-inverted
></v-autocomplete>
</template>
<script>
import _ from "lodash";
export default {
data: () => ({
games: [], // this is where all the game data will be stored
isLoading: true, // variable to determine if the results are still being fetched from the API
search: null // this is where the query will be stored
}),
methods: {
getGames(params = "") {
// this function will fetch game data from https://api.rawg.io/api/games with whatever api parameters you pass to the parameter `params`
this.axios
.get("https://api.rawg.io/api/games" + params)
.then(resp => {
// fetch data
let tempGames = [...this.games.slice(0), ...resp.data.results]; //copy of this.games + new data
this.games = _.uniqBy(tempGames, "id"); // remove any duplicates
this.isLoading = false; // now that the data is in the array `games`, we can set isLoading to false
})
.catch(e => {
// code to run if there was an error
console.error(e); // display error message
});
},
searchGames(query) {
// this function will call getGames() with the search query formatted as an API parameter (?search=YOUR_QUERY)
let searchQuery = encodeURI("?search=" + query); // URI encode the query so it is able to be fetched properly
this.getGames(searchQuery);
}
},
watch: {
search: _.debounce(function(query) {
// debounce with a a value of 250 will allow this function to be every 250 milliseconds at most. So if the user is typing continually, it won't run until the user stops.
this.searchGames(query);
}, 250)
},
created() {
this.getGames(); // load the first 20 games initally
}
};
</script>
这将:
- 加载前 20 个游戏
- 当您输入查询并停止输入时,它将执行对
https://api.rawg.io/api/games?search=YOUR_QUERY
的请求,并将结果添加到games
数组。 (所以每次你搜索一些东西,saved games 数组都会增加。这意味着如果你搜索同一个游戏两次,虽然它仍然会用https://api.rawg.io/api/games?search=YOUR_QUERY
在线搜索,但游戏已经在 games 数组中了从第一次开始,所以它会立即加载。) v-autocomplete
过滤并显示结果。
此方法在更快的连接上效果更好,因为结果加载速度更快。因此,如果您的连接速度较慢,则加载结果可能需要一些时间。不幸的是,这是无法解决的问题(虽然您可以预先加载大量数据,但不能保证您加载的是用户将搜索的内容)
导航栏的图形问题已通过将 App.vue 中的父 <div>
更改为 <v-app>
解决,如下所示:
之前:
<template>
<div id="app">
<nav-bar></nav-bar>
...
</div>
</template>
之后:
<template>
<v-app id="app">
<nav-bar></nav-bar>
...
</v-app>
</template>
我还添加了 lodash
作为去抖动(等待用户停止输入)和删除重复项的依赖项。
这是我正在处理的 codepen。
如果您还有其他问题,请告诉我。