Nuxt.jsにページネーションを設置する~Vuejs-paginate編

  • 公開日アイコン
  • 更新日アイコン
Nuxt.jsにページネーションを設置する~Vuejs-paginate編 メイン画像

Ad Area

Nuxt.jsにページネーションを付けるために、Vue.jsのパッケージVuejs-paginateを導入した。

導入方法

Vuejs-paginateに限らず、Nuxt.jsで外部パッケージを追加するとwindow is not definedのエラーが出るので、pluginを作成してグローバルコンポーネントとして登録する。

plugins/vuejs-paginate.js
import Vue from 'vue';
import Paginate from 'vuejs-paginate';

Vue.component('paginate', Paginate)
nuxt.config.js
  plugins: [
    {src: '~/plugins/vuejs-paginate', ssr:false },
  ],

プラグインのbuildオプションをclientでのみ実行するように設定する。Nuxt.js 2.14.x以降はmode:'cliant'といった記述方法が非推奨になったため、ssr:falseとする。

ページネーションメソッドの設定

index.vue
<script>
export default {
  data () {
    return {
    items: '',
    parPage: '',
    currentPage: '',
    };
  },
  methods: {
    clickCallback: function (pageNum) {
      this.currentPage = Number(pageNum);
    }
   },
  computed: {
    posts: function() {
      let current = this.currentPage * this.parPage;
      let start = current - this.parPage;
      return this.items.slice(start, current);
    },
    getPageCount: function() {
      return Math.ceil(this.items.length / this.parPage);
    }
   },

  async asyncData ({ $content }) {
    const items = await $content('post')
      .sortBy('published', 'desc')
      .fetch()
    const parPage = 12;
    const currentPage = 1;
    return { items, parPage, currentPage }
  },
}
</script>

dataプロパティ

  • items…アイテムの配列。nuxt/contentで記事を作成している当ブログの場合はpostフォルダ内から取得している。
  • parPage…1ページに表示するアイテム数
  • currentPage…現在のページ番号(1から始まる)

methods

  • clickCallback…ページネーションクリック時にcurrentPageへページ番号を設定

computed

  • posts…現在のページのアイテムを返す。当ブログの場合はCardコンポーネントへも渡している。
  • getPageCount…ページネーションの最大ページ数(itemsparPageで割って切り上げ)

テンプレート部分

index.vue
<template>
  <main role="main">
    <CardList :posts="posts"/>
    <client-only placeholder="Loading...">
      <paginate v-if="(getPageCount > 1)"
        :page-count="getPageCount"
        :page-range="3"
        :margin-pages="2"
        :click-handler="clickCallback"
        :prev-text="'前へ'"
        :next-text="'次へ'"
        :container-class="'pagination flex justify-center mb-6'"
        :page-class="'c-pagination-item'"
        :page-link-class="'c-pagination-item__link'"
        :prev-class="'c-pagination-btn c-pagination-prev'"
        :prev-link-class="'c-pagination-btn__link'"
        :next-class="'c-pagination-btn c-pagination-next'"
        :next-link-class="'c-pagination-btn__link'"
        :hide-prev-next="true"
        >
      </paginate>
    </client-only>
  </main>
</template>

以下は当ブログ独自に追加したもの

  • <client-only placeholder="Loading..."> </client-only>の部分はwindow is not definedエラー対策。
  • v-if="(getPageCount > 1)"…デフォルトだと1ページのみの場合もページネーションが出てしまうので、2ページ以上の時に表示されるようにするための処理。

プロパティ

当ブログで使用しているものを抜粋

名前 タイプ 説明
page-count 数値 総ページ数(必須)。上記テンプレートの場合getPageCountに渡されている。
page-range 数値 表示されるページ数(アクティブページの前後に同じページ数表示されるようにするため、奇数推奨)。デフォルト値:3
margin-pages 数値 余白のページ表示数。デフォルト値:1
prev-text 文字列 「前へ」ボタンのテキスト。HTML使用可。デフォルト値:prev
next-text 文字列 「次へ」ボタンテキスト。HTML使用可。デフォルト値:next
click-handler 関数 ページをクリックした時に呼び出すメソッド。クリックされたページ番号をパラメーターとして使用する。
container-class 文字列 ページネーションを囲むコンテナのclass
page-class 文字列 ページ要素のliタグのclass
page-link-class 文字列 ページ要素のaタグのclass
prev-class 文字列 「前へ」ボタン要素liタグのclass
prev-link-class 文字列 「前へ」ボタン要素aタグのclass
next-class 文字列 「次へ」ボタン要素liタグのclass
next-link-class 文字列 「次へ」ボタン要素aタグのclass
hide-prev-next 真偽 前/次のページがない場合はボタンを表示しない。デフォルト値:false(表示)

CSSでスタイルを当てる

container-classにはtailwindcssのflex justify-center mb-6のclassが当てられているので、それ以外のパーツをcssで装飾する。

.c-pagination-btn__link,
.c-pagination-item__link {
  border: solid 2px #3A3F58;
  border-radius: 4px;
  text-align: center;
  padding: .5rem 1rem;
  margin: 0 .25rem;
  display: block;
}
.c-pagination-btn__link:hover,
.c-pagination-item__link:hover {
  background-color: #3A3F58;
  color: #fff;
}
.active .c-pagination-item__link {
  background-color: #3A3F58;
  color: #fff;
  pointer-events: none;
}

参考ページ

Ad Area