😺

【Vue3】v-paginationでページネーションを実装

2023/08/04に公開

公式

Pagination
Data table - Pagination

コード

データはバックエンドからjsonで返ると想定しています。
今回は、以下の2通りのケースで考えます。

  1. ページ番号を押すたびにAPIリクエストしない
  2. ページ番号を押すたびにAPIにリクエストする
    a. コンポーネント内でv-paginationが使われると想定

1. ページ番号を押すたびにAPIリクエストしない場合

ページ番号を押すたびにAPIリクエストしない場合、初期表示の際バックエンドから与えられたデータを元に、1ページの最大表示数などを管理します。

template

<v-pagination
 v-model="currentPage"
 :length="getPageCount"
 :click-handler="clickCallback"
</v-pagination>

script

<script>
  export default {
    data () {
      return {
        currentPage: 1, // 現在のページ
        perPage: 10, // 1ページの最大表示数
	items: [] // jsonで入ってくることを想定
      }
    },
    mounted() {
      // 初期表示
     axios.get(url)
      .then(res => this.items = res.data)
      .catch(err => err.response)
    },
    methods: {
    //現在のページを決める
      clickCallback(pageNum) {
       this.currentPage = Number(pageNum)
      }
    },
    computed: {
     //必要なデータだけ表示
     getList() {
      const current = this.currentPage * this.perPage
      const start = current - this.perPage
      return this.items.slice(start, current)
     },
     //総ページ数を決める
     getPageCount() {
      return Math.ceil(this.items.length / this.perPage)
     }
    }

2. ページ番号を押すたびにAPIにリクエストする

この場合、コンポーネント内でv-paginationが使われると想定します。
ページ番号がクリックされた時、そのページ番号に対応したデータをAPIから受け取るといったイメージです。
流れとしては、以下のようになります。

  1. v-paginationを含む子コンポーネントでページ番号をemitする
  2. 親コンポーネントでemitされた値を受け取る
  3. APIにリクエストする(略)

子コンポーネントでページ番号をemitする

子コンポーネント

<div>
 <v-pagination
  v-model="currentPage"
  :length="getPageCount"
  @click="emit('pagination', currentPage)"
 </v-pagination>
</div>
...略...
emits: ['pagination']

親コンポーネントでemitされた値を受け取る

イベントの引数をdata()pageに代入するのですが、
イベントハンドラーがメソッドの場合、その値はメソッドの最初のパラメーターとして渡されるため以下のように書く事ができます。

親コンポーネント

<Child @pagination="changePageNum" />

...略...
data() {
 return {
  page: 0
 }
},
methods: {
 changePageNum(e) {
  this.page = e
 }
}

参考

Vue.jsでページネーションを実装

イベントの引数

コンポーネントのイベント

Discussion