You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调用API获取所需数据并减少Vue.js中的监听器数量

Solution: Fetch More Anime Data & Avoid Extra Vue Watchers

Hey there! Let's break down how to solve both of your issues step by step.

1. Modify the API Call to Fetch Full Anime Data

Right now, your animeFind function only extracts the image URL. We'll adjust it to store the complete anime object (including title, episode count, synopsis, etc.) so you can access all the data you need. If you want detailed episode lists (not just the total count), we can also add an optional call to Jikan's episodes endpoint.

2. Avoid Extra Vue Watchers

Instead of writing duplicate watchers for anime1 and anime2, we'll reuse a single handler function. This makes scaling easier if you ever need to add more anime entries later—no extra watchers required.

Modified Component Code

Here's the updated code with both changes implemented:

<template>
  <section class="container">
    <!-- Anime 1 Column -->
    <div class="column" v-if="animeData1">
      <img :src="animeData1.image_url" alt="Anime 1 cover" />
      <h2>{{ animeData1.title }}</h2>
      <p>Total Episodes: {{ animeData1.episodes }}</p>
      <p>{{ animeData1.synopsis }}</p>
      <!-- Optional: Show truncated episode list if fetched -->
      <div v-if="animeData1.episodesList">
        <h3>Latest Episodes</h3>
        <ul>
          <li v-for="ep in animeData1.episodesList.slice(-5)" :key="ep.episode_id">
            Ep {{ ep.episode_id }}: {{ ep.title }}
          </li>
        </ul>
      </div>
    </div>

    <!-- Anime 2 Column -->
    <div class="column" v-if="animeData2">
      <img :src="animeData2.image_url" alt="Anime 2 cover" />
      <h2>{{ animeData2.title }}</h2>
      <p>Total Episodes: {{ animeData2.episodes }}</p>
      <p>{{ animeData2.synopsis }}</p>
      <!-- Optional: Show truncated episode list if fetched -->
      <div v-if="animeData2.episodesList">
        <h3>Latest Episodes</h3>
        <ul>
          <li v-for="ep in animeData2.episodesList.slice(-5)" :key="ep.episode_id">
            Ep {{ ep.episode_id }}: {{ ep.title }}
          </li>
        </ul>
      </div>
    </div>

    <!-- Error Display -->
    <div v-if="error" class="notification is-danger">{{ error.message }}</div>
  </section>
</template>

<script>
import axios from "axios";
import Buefy from "buefy";
import "buefy/dist/buefy.css";
import Vue from "vue";

Vue.use(Buefy);

export default {
  props: {
    anime1: String,
    anime2: String,
  },
  data() {
    return {
      // Store full anime objects instead of just image URLs
      animeData1: null,
      animeData2: null,
      error: null,
    };
  },
  methods: {
    async fetchAnimeData(searchQuery, targetKey) {
      try {
        // First search for the anime to get its MAL ID
        const searchResponse = await axios.get(`https://api.jikan.moe/v3/search/anime?q=${searchQuery}`);
        const animeId = searchResponse.data.results[0].mal_id;

        // Fetch core anime details
        const animeDetails = await axios.get(`https://api.jikan.moe/v3/anime/${animeId}`);
        this[targetKey] = animeDetails.data;

        // Optional: Fetch detailed episode list (uncomment to enable)
        // const episodeData = await axios.get(`https://api.jikan.moe/v3/anime/${animeId}/episodes`);
        // this[targetKey].episodesList = episodeData.data.episodes;
      } catch (err) {
        this.error = err;
        console.error("Failed to fetch anime data:", err);
      }
    },
  },
  watch: {
    // Reuse the same handler logic for both props
    anime1: {
      immediate: true,
      handler(newVal) {
        if (newVal) this.fetchAnimeData(newVal, "animeData1");
      },
    },
    anime2: {
      immediate: true,
      handler(newVal) {
        if (newVal) this.fetchAnimeData(newVal, "animeData2");
      },
    },
  },
};
</script>

Key Improvements:

  • Switched to async/await for cleaner, more readable asynchronous code (no nested .then() chains)
  • Stored full anime objects in data so you can access any field from the API response (title, synopsis, episode count, etc.)
  • Used conditional rendering (v-if) to avoid showing empty content before data loads
  • Reused a single fetchAnimeData method for both anime entries, cutting down on duplicate code
  • Added an optional episode list fetch (commented out) for when you need detailed episode information

If you ever need to add more anime entries (like anime3), you only need to:

  1. Add the new prop (e.g., anime3: String)
  2. Add a new data property (e.g., animeData3: null)
  3. Add a new watch entry using the same fetchAnimeData method—no new handler logic required!

内容的提问来源于stack exchange,提问作者A.K.M. Adib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:57:50