vue3+railsでのvuejs-paginate-nextを使用したページネーションの実装方法

javascript

本記事では、vue3のscript setupを使用したページネーション機能を作成する方法について解説します。

使用するライブラリはvuejs-paginate-nextです。コピーしてそのまま使用してもらえるようにコンポーネント化しましたので、vueでページネーション機能を実装したい方はぜひ使用していただければと思います!

今回の環境

  • vue: 3.2.13
  • rails: 6.1.7.3
  • vuejs-paginate-next: 1.0.2

今回作成するのページネーションについて

今回は、rails APIモードでfrontendはvue.jsを使用する想定です。

APIモードページネーションを作成するには、

  • frontendに全データを渡してfrontend上で分割処理する
  • frontendからページネーションに必要なparamsをAPIで渡して分割処理はbackendで行う

今回は、下の方法での実装をやっていきたいと思います。ページネーションを作成する上で、ページネーション化させたいデータが大規模だとbackend→frontendにデータを渡すのに時間がかかってしまいます(ただし、一度呼び込んで仕舞えばフロントエンドでの処理になる為、ページ遷移は早く、逆に下の方法だと、ページネーションの度にAPIを呼ぶのでリクエスト回数が増えるというデメリットもあります)。

どちらかといえば、実装自体は下の方法の方が大変だと思うので、もし上の方法で実装したい場合でも本記事を参考にしていただけると作りやすいと思います!

vue3でvuejs-pagination-nextを使用したページネーションを作成する

それでは早速コードを紹介しようと思います。frontendapp(アプリ)/src/components/Pagination.vueを作成して下記をコピーしてください。

<script setup>
import Paginate from "vuejs-paginate-next";
import { defineProps, defineEmits } from "vue";

const props = defineProps({
  pageCount: {
    type: Number,
  },
});

const emits = defineEmits(["changePage"]);

const paginateClickCallback = function (pageNum) {
  emits("changePage", pageNum);
};
</script>
<template>
  <Paginate
    :page-count="props.pageCount"
    :prev-text="'≪'"
    :next-text="'≫'"
    :click-handler="paginateClickCallback"
    :container-class="'Pagination'"
    :page-class="'Pagination-Item'"
    :page-link-class="'Pagination-Item-Link'"
    :prev-class="'Pagination-Item'"
    :prev-link-class="'Pagination-Item-Link'"
    :next-class="'Pagination-Item'"
    :next-link-class="'Pagination-Item-Link'"
    :active-class="'Pagination-Item-Link isActive'"
  />
</template>

続いて、実際にコンポーネントを使用する画面です。frontendapp(アプリ)/src/views/ResultList.vueにページネーション機能を取り込みたいと思います。各々取り入れたいページにて下記を記載してください。

また、axiosの処理では、ページネーションしたいデータを取得するAPI(url)を指定しています。このAPIのデータをページネーションしたい!っていうのはそこのurlを記載してください。特になくてとりあえず動きを確認したい方は下記のように記載してみてください。

<script setup>
import Pagination from "@/components/Pagination";
import { ref, onMounted } from "vue";

const PER_PAGE = 12;
const paginateItems = ref(null);
const pageCount = ref(0);
const pageNum = ref(1); // 初期値は1(1ページ目とするため)

const searchItems = function (pageNum) {
  axios
    .get(/items, { // 取得したいAPIがある場合はurlを変更してください
      params: {
        page: pageNum,
        per_page: PER_PAGE,
      },
    })
    .then((response) => {
      paginateItems.value = response.data.items;
      pageCount.value = response.data.metadata.total_page;
    });
};

// ページネーションのリンクをクリックしたときに走る処理
const updatePaginateItems = function (pageNum) {
  searchItems(pageNum);
};
</script>

<template>
<div class="dataarea">
    <li
    v-for="item in paginateItems"
    :key="item.id"
    >
      <div class="col_rgt">
        <ul>
          <div>
            <p>{{ item.id }}</p>
          </div>
          <div>
            <p>{{ item.name }} points</p>
          </div>
        </ul>
     </div>
   </li>
<div class="col_rgt">
    <Pagination
    :pageCount="pageCount"
    v-model="pageNum"
    @changePage="updatePaginateItems"
    />
</div>
<template>

rails側のページネーション処理を作成する

まだkaminariをインストールしていない人はインストールするところから始めます。

gem 'kaminari'

上記をgemfileに記載してbundle installしてください。

今回は、itemsコントローラを指定して、idとnameだけ表示するものを作成します。今回はサンプルなので、scaffoldでモデル、マイグレーションファイル、コントローラ、ルーティングを一括作成します。

rails g scaffold Item name:string

itemsコントローラに下記を記載してください。

class ItemsController < ApiController
  def index
    items = Item.all.page(page_param).per(per_page_param)
  end

  private
   def per_page_param
    params[:per_page]&.to_i
  end

  def page_param
    params[:page]&.to_i
  end
end

以上で、セットアップは完成です。

一応データの動きを見るためにサンプルを動かしてみましょう。db/seeds.rbにシードデータを作成して、実際にモデルにデータを入れてみましょう

20.times do |n|
  Item.create!(
    name: "テストユーザー#{n + 1}",
  )
end

作成後、下記を実行してください。

rails db:create # databaseを作成していない場合
rails db:migrate
rails db:seed

上記でセットアップが完了です。これでページネーションが反映されていると思います!

まとめ

以上、vue3+railsでpagination機能を実装する方法の解説を行いました!

frontendについてはそのまま使用できると思うので、ぜひ使っていただいてスムーズにページネーション機能を実装していただければ!

コメント

タイトルとURLをコピーしました