VueでWordPressのRestAPIページネーションを実装したい

ページネーションを実装したいんだけど埒が明かなかったので聞いてみました。

記事が合計14個あり、1記事ずつ表示した場合 以下のページングが表示されるようなコードに書き換えられますか?

・5記事目を表示した場合(5は隣り合った2つまでのページを表示’34と67′)
< 1 … 3 4 5 6 7 … 14 >

・2記事目を表示した場合
< 1 2 3 4 … 14 >

・1記事目を表示した場合(1は最初なので<を消す)
1 2 3 … 14 >

・14記事目を表示した場合(14は最後なので>を消す)
< 1 … 12 13 14

以下にあなたの要件に基づいてVue.jsでのページネーションの実装例を示します。ただし、このサンプルコードはVue 3のComposition APIを使用しています。

<template>
  <div>
    <!-- Single Post -->
    <div v-for="post in posts" :key="post.id">{{ post.title.rendered }}</div>

    <!-- Pagination -->
    <div>
      <button @click="prevPage" :disabled="currentPage <= 1"><</button>
      <span v-if="currentPage > 3">1 … </span>
      <span v-for="n in surroundingPages" :key="n">
        <button @click="goToPage(n)" :disabled="n === currentPage">{{n}}</button>
      </span>
      <span v-if="currentPage < totalPages - 2"> … {{totalPages}}</span>
      <button @click="nextPage" :disabled="currentPage >= totalPages">></button>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, computed } from "vue";

export default {
  setup() {
    const posts = ref([]);
    const currentPage = ref(1);
    const totalPages = ref(0);

    const getPosts = async () => {
      const response = await fetch(`${window.location.origin}/wp-json/wp/v2/posts?page=${currentPage.value}&categories=<?php echo $catid_news;?>`);
      totalPages.value = parseInt(response.headers.get('X-WP-TotalPages'));
      posts.value = await response.json();
    };

    const nextPage = () => {
      if (currentPage.value < totalPages.value) {
        currentPage.value++;
        getPosts();
      }
    };

    const prevPage = () => {
      if (currentPage.value > 1) {
        currentPage.value--;
        getPosts();
      }
    };

    const goToPage = (page) => {
      currentPage.value = page;
      getPosts();
    };

    const surroundingPages = computed(() => {
      let start = Math.max(1, currentPage.value - 2);
      let end = Math.min(totalPages.value, currentPage.value + 2);

      if (currentPage.value <= 3) {
        end = Math.min(4, totalPages.value);
      }

      if (currentPage.value >= totalPages.value - 2) {
        start = Math.max(1, totalPages.value - 3);
      }

      return Array.from({ length: end - start + 1 }, (_, i) => start + i);
    });

    onMounted(getPosts);

    return { posts, currentPage, totalPages, nextPage, prevPage, goToPage, surroundingPages };
  },
};
</script>

このコードでは、周囲のページ番号を計算するためのsurroundingPagesというcomputedプロパティを作成しています。現在のページ番号が3以下の場合、または最大ページ番号から2以下の場合は、最初または最後の4ページを表示します。それ以外の場合は、現在のページの前後2ページを表示します。

この実装では、それぞれのページ番号のボタンにクリックイベントを設定し、そのページへ移動するようにしています。また、現在のページのボタンはdisabledになります。

このサンプルコードは基本的なページネーションの機能を実装していますが、あなたのアプリケーションに合わせて適宜カスタマイズしてください。

2023-05-21