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

Vue3新闻应用Load More按钮无法及时隐藏且点击无加载的问题排查

新闻API加载更多功能的错误排查与修复

问题背景

我使用Vue3和News API开发新闻应用,正在实现“加载更多文章”功能:初始加载24篇文章,当总文章数大于当前已加载数量时,页面底部显示“Load more articles”按钮。但最后一次点击按钮时,按钮消失前未加载新文章,且API响应返回错误码maximumResultsReached。

现有代码

ArticleList.vue

<template>
  <div v-if="articles && articles.length" class="row">
    <div
      v-for="article in articles"
      :key="article._id"
      class="col-xs-12 col-sm-6 col-lg-4 col-xl-3"
    >
      <ArticleCard :article="article" />
    </div>
    
    <div v-show="isMore" class="mb-3 text-center">
      <LoadMoreButton @load-more="loadMore" text="Load more articles" />
    </div>
  </div>
  <p v-if="totalResults == 0" class="text-center">No articles to display</p>
</template>

<script>
import ArticleCard from "./ArticleCard.vue";
import LoadMoreButton from "./LoadMoreButton.vue";

export default {
  name: "NewsList",
  components: { ArticleCard, LoadMoreButton },

  props: {
    whatToShow: {
      type: String,
      required: true,
    },

    searchString: {
      type: String,
      required: true,
      default: "",
    },
  },

  data: () => ({
    language: "en",
    page_size: 24,
    current_page: 1,
    totalResults: 1,
    articles: [],
  }),

  mounted() {
    this.getArticles();
  },

  watch: {
    whatToShow() {
      this.getArticles();
    },

    searchString() {
      this.getArticles();
    },
  },

  computed: {
    isMore() {
      // Check if the total number of pages is grater then the current page
      let totalPages = Math.ceil(this.totalResults / this.page_size);
      return totalPages > this.current_page;
    },
  },

  methods: {
    getArticles() {
      const endpoint = `${process.env.VUE_APP_API_URL}/${this.whatToShow}?q=${this.searchString}&language=${this.language}&pageSize=${this.page_size}&page=${this.current_page}&apiKey=${process.env.VUE_APP_API_KEY}`;

      this.$axios
        .get(endpoint)
        .then((response) => {
          this.totalResults = response.data.totalResults;
          this.articles = [...this.articles, ...response.data.articles];
        })
        .catch((err) => console.log(err));
    },

    loadMore() {
      if (this.isMore) {
        this.current_page++;
        this.getArticles();
      }
    },
  },
};
</script>

LoadMoreButton.vue

<template>
  <button class="btn btn-md btn-success" @click="$emit('load-more')">
    {{ text }}
  </button>
</template>

<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "LoadMoreButton",

  props: {
    text: {
      type: String,
      required: false,
      default: "Load more",
    },
  },
});
</script>

错误原因分析

  1. isMore计算逻辑偏差:用totalPages > current_page判断是否有更多文章,当current_page等于最后一页时按钮会隐藏,但此时用户可能已点击按钮,导致current_page加1后超出API允许的最大页码,触发maximumResultsReached错误。
  2. 查询重置逻辑缺失:whatToShow或searchString变化时,未重置current_page和articles数组,导致新旧数据混叠,页码计算错误。
  3. API结果限制未处理:News API免费版有最大返回结果数限制(通常为100篇),当实际可获取文章数小于计算出的totalPages * page_size时,最后一次请求会触发错误。

修复方案

1. 修正isMore判断逻辑

直接对比已加载文章数和总结果数,避免页码计算误差:

computed: {
  isMore() {
    return this.articles.length < this.totalResults;
  },
}

2. 完善查询重置逻辑

切换查询条件时,重置页码和文章数组,确保每次查询从头开始:

watch: {
  whatToShow() {
    this.current_page = 1;
    this.articles = [];
    this.getArticles();
  },

  searchString() {
    this.current_page = 1;
    this.articles = [];
    this.getArticles();
  },
},

3. 捕获API错误并更新状态

遇到maximumResultsReached错误时,将totalResults设为已加载文章数,避免按钮继续显示:

getArticles() {
  const endpoint = `${process.env.VUE_APP_API_URL}/${this.whatToShow}?q=${this.searchString}&language=${this.language}&pageSize=${this.page_size}&page=${this.current_page}&apiKey=${process.env.VUE_APP_API_KEY}`;

  this.$axios
    .get(endpoint)
    .then((response) => {
      this.totalResults = response.data.totalResults;
      this.articles = [...this.articles, ...response.data.articles];
    })
    .catch((err) => {
      console.log(err);
      // 处理最大结果数限制错误
      if (err.response?.data?.code === "maximumResultsReached") {
        this.totalResults = this.articles.length;
      }
    });
},

4. 优化loadMore触发逻辑

保留原逻辑即可,确保只有在isMore为真时才加载下一页:

loadMore() {
  if (this.isMore) {
    this.current_page++;
    this.getArticles();
  }
}

额外建议

  • 添加加载状态,防止用户重复点击按钮;
  • 对searchString做防抖处理,减少不必要的API请求;
  • 查阅News API文档确认免费版最大返回数,在前端添加相应提示。

内容的提问来源于stack exchange,提问作者Razvan Zamfir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:20:38