如何在 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>


这将:

  1. 加载前 20 个游戏
  2. 当您输入查询并停止输入时,它将执行对 https://api.rawg.io/api/games?search=YOUR_QUERY 的请求,并将结果添加到 games 数组。 (所以每次你搜索一些东西,saved games 数组都会增加。这意味着如果你搜索同一个游戏两次,虽然它仍然会用 https://api.rawg.io/api/games?search=YOUR_QUERY 在线搜索,但游戏已经在 games 数组中了从第一次开始,所以它会立即加载。)
  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

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