KurocoとNuxt.jsで、コンテンツ一覧ページにページネーションを実装する

コンテンツの数が多い場合、コンテンツ一覧を複数のページに分割するページネーションの実装が必要になる場合があります。
Kurocoのトピックスリストのエンドポイントは、レスポンスに記事数・現在のページ・ページ数の合計 などが含まれるため、フロント側でページ数の計算をすることなくページネーションの実装が可能です。

本チュートリアルではKurocoとNuxt.jsで、コンテンツ一覧ページを作成するで作成したコンテンツ一覧ページ(お知らせ一覧)にページネーションを実装する方法を説明します。

このページはKurocoとNuxt.jsでのプロジェクトが構築済みであり、コンテンツ一覧のページが作成されていることを前提としています。
まだ構築していない場合は、下記のチュートリアルを参照してください。
Kurocoビギナーズガイド
KurocoとNuxt.jsで、コンテンツ一覧ページを作成する

Kurocoで1ページ当たりの表示数を設定

1ページ当たりのコンテンツ表示数は固定になるため、Kurocoの管理画面側でパラメータの設定をします。 エンドポイントに表示するページの情報をパラメータとして渡すことで、各ページのレスポンスを得ていきます。

お知らせ一覧のエンドポイントを作成したAPIのページに遷移します。 Image (fetched from Gyazo)

お知らせ一覧のエンドポイント(今回の場合は /rcms-api/1/news)の[更新]をクリックします。
Image (fetched from Gyazo)

エンドポイントの設定画面が開くので、中ほどのcntに1ページ当たりの表示数を入力します。今回は4と入力し[更新]をクリックします。
Image (fetched from Gyazo) Image (fetched from Gyazo)

Swagger UIで各ページの情報が取得できることを確認する

次にエンドポイントからのレスポンスを確認します。
「お知らせ一覧」のエンドポイントを作成したAPIのページに遷移します。
Image (fetched from Gyazo)

[Swagger UI]をクリックします。
Image from Gyazo

「お知らせ一覧」のエンドポイントの[Try it out]をクリックします。
Image (fetched from Gyazo)

pageIDに1を入力します。
Image (fetched from Gyazo)

[Execute]をクリックします。
Image (fetched from Gyazo)

レスポンスを確認すると1ページ目の4件のリストと、pageInfoの情報が確認できます。
Image (fetched from Gyazo)

同様にpageIDにページ数を入力して[Execute]をクリックすると、各ページのリストと、pageInfoのレスポンスが得られます。
こちらを利用してフロントでページネーションを実装してきます。

ページを動的に作成する

Nuxt.js ではディレクトリ名やファイル名を_(アンダースコア)から始まる名前に設定すると、ページを動的に作成できます。
「index.vue」のファイルを/news/list/のディレクトリにコピーし、ファイル名を_page.vueに変更します。

ページを動的に作成した場合、/news/list/1のURLでアクセスした際の1の部分を{{ this.$route.params.page }} で表示できます。
下記のように<p>ニュース一覧ページ{{ this.$route.params.page }}</p>を追加して、表示を確認します。

/pages/news/list/_page.vue
<template>
  <div>
    <p>ニュース一覧ページ{{ this.$route.params.page }}</p>
    <div v-for="n in response.list" :key="n.slug">
      <nuxt-link :to="'/news/' + n.slug">{{ n.ymd }} {{ n.subject }}</nuxt-link >
    </div>
  </div>
</template>

<script>
export default {
    async asyncData ({ $axios }) {
        try {
          const response = await $axios.$get(process.env.BASE_URL + '/rcms-api/1/news')
          return { response }
        }catch (e) {
            console.log(e.message)
        }
    }
}
</script>

http://localhost:3000/news/list/1のURLで下記のように現在のページ数が表示できていることを確認できます。
Image (fetched from Gyazo)

この時点ではKurocoへのエンドポイントにページ数の情報を送っていないため、どのURLでアクセスしても表示されるお知らせは同じになります。

現在のページ情報をパラメータに追加する

次に、現在のページの情報をパラメータに追加し、各ページに対応するレスポンスを得ます。
_page.vueを下記のように修正します。

/pages/news/list/_page.vue
<template>
  <div>
    <p>ニュース一覧ページ{{ this.$route.params.page }}</p>
    <div v-for="n in response.list" :key="n.slug">
      <nuxt-link :to="'/news/' + n.slug">{{ n.ymd }} {{ n.subject }}</nuxt-link >
    </div>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios, params }) {
    try {
      const response = await $axios.$get(
        process.env.BASE_URL + '/rcms-api/1/news',{
          params: {
            pageID: params.page
          },
        }
      )
      return { response }
    } catch (e) {
      console.log(e.message)
    }
  },
}
</script>

今度はアクセスするURLによって、表示されるお知らせの一覧が変更されることを確認できます。
Image (fetched from Gyazo)

ページ遷移のためのリンクを表示する

次にページを遷移するためのリンク部分を作成します。
エンドポイントからのレスポンスのpageInfoに現在のページ数や最終ページの情報が含まれるので、こちらを利用します。
ここでは簡単な例として下記のように記述を追加します。

/pages/news/list/_page.vue
<template>
  <div>
    <p>ニュース一覧ページ{{ this.$route.params.page }}</p>
    <div v-for="n in response.list" :key="n.slug">
      <nuxt-link :to="'/news/' + n.slug">{{ n.ymd }} {{ n.subject }}</nuxt-link>
    </div>

    <ul style="list-style: none; display: flex">
      <li v-if="response.pageInfo.pageNo === 1">前へ</li>
      <li v-else><nuxt-link :to="'/news/list/' + (response.pageInfo.pageNo -1)">前へ</nuxt-link></li>
      <li v-for="i in response.pageInfo.totalPageCnt" :key="i">        
        <nuxt-link :to="'/news/list/' + i">{{i}}</nuxt-link>
      </li>
      <li v-if="response.pageInfo.pageNo === response.pageInfo.totalPageCnt">次へ</li>
      <li v-else><nuxt-link :to="'/news/list/' + (response.pageInfo.pageNo +1)">次へ</nuxt-link></li>
    </ul>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios, params}) {
    try {
      const response = await $axios.$get(
        process.env.BASE_URL + '/rcms-api/1/news',
        {
          params: {
            pageID: params.page,
          },
        }
      )
      return { response }
    } catch (e) {
      console.log(e.message)
    }
  },
}
</script>

各ページへのリンクが追加できました。
Image (fetched from Gyazo)

最後に/news/list/のURLでもアクセスできるよう_page.vueのファイルをコピーしてindex.vueを作成しておきます。

pages
 - news
   - list
     - _page.vue
     - index.vue 

Image (fetched from Gyazo)

以上で、KurocoとNuxt.jsで、コンテンツ一覧ページにページネーションを実装する方法の説明を終わります。

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。