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

この記事は最終更新日から 1 年以上が経過しており、内容が古くなっている可能性があります。

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

導入方法

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

import Vue from "vue";
import Paginate from "vuejs-paginate";

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

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

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

<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で割って切り上げ)

テンプレート部分

<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: 0.5rem 1rem;
  margin: 0 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;
}

参考ページ

Suzunatsu

このブログについて

コーディングやWeb関連技術の記事と、買い物など日々のメモから成り立っています。 →少しだけ詳しく

この記事がお役に立ちましたら、サポートをお願いします。

広告