如何在VueJS的搜索栏中实现API?

问题描述

我正在从事一个大学项目,我一直试图实现一个从API(https://api.rawg.io/api/games获取游戏名称搜索栏,并在点击游戏后将用户重定向到带有特定的游戏网址。现在,我希望至少能够完成第一部分。

我已经创建了searchbar.vue组件,并从官方Vuetify库中复制了代码: (https://github.com/vuetifyjs/vuetify/blob/master/packages/docs/src/examples/autocompletes/simple/api.vue

但是,如果我将API从它们提供的示例更改为我需要的(原始),它将不再起作用,我不确定为什么。

如何使搜索栏工作?

我正在提供一个指向我当前正在使用的codeandBox链接,以备不时之需: (https://codesandbox.io/s/searchbar-mtjr2?file=/src/components/searchbar.vue

如有需要,我会尽力提供有关此问题的更多信息。

非常感谢您考虑这篇文章

解决方法

我相信搜索栏的所有问题都已解决: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>


这将:

  1. 加载前20场游戏
  2. 输入查询并停止键入时,它将执行对https://api.rawg.io/api/games?search=YOUR_QUERY的请求,并将结果添加到games数组中。 (因此,每次您搜索事物时,保存的游戏数组都会增加。这意味着,如果您两次搜索同一个游戏,而该游戏仍将使用https://api.rawg.io/api/games?search=YOUR_QUERY在线搜索,则该游戏将已经存在于游戏数组中从第一次开始,因此它将立即加载。)
  3. 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

如果还有其他问题,请告诉我。