vue.js+vuetifyでページネーション

## 概要
ページネーションを作成してみようと調べたのでメモしておく。

とりあえず、ページネーションに専念したいので、データの取得等は省略します。
また、vuetify自体のインストールは、別途下記ページで記述しているので省略します。

* [Vuetifyをインストールして使ってみる](https://qiita.com/reflet/items/88dc298c8887ad517845)

## プラグイン作成
共通処理を使い回せるようにプラグインにしておく。
計算関連やページネーションの情報は、このプラグインに集約しておく。

```js:plugins/pagination.js
const Pagination = {
  install (Vue, options) {
    const store = new Vue({
      data: {
        current       : 0,   // 現在のページ番号
        visible       : 7,   // ページネーションのリンクに表示するページ数
        total         : 0,   // ページの総数
        rows          : 0,   // データの総数
        rows_per_page : 10   // 1ページに表示するデータの件数
      }
    });

    function setTotal() {
      store.total = Math.ceil(store.rows / store.rows_per_page);
    }

    Vue.prototype.$page = {
      get current() {
        return store.current;
      },
      get visible() {
        return store.visible;
      },
      get total() {
        return store.total;
      },
      set current(num) {
        const current = (num != null) ? parseInt(num) : 1;
        store.current = Math.max(1, Math.min(current, store.total));
      },
      set rows(num) {
        store.rows = (num != null) ? parseInt(num) : 0;
        setTotal();
      },
      set rowsPerPage(num) {
        store.rows_per_page = (num != null) ? parseInt(num) : 0;
        setTotal();
      }
    }
  }
};
export default Pagination
```

## 作ってみる
コンポーネントを作成してみる。

```vue:List.vue
<template>
  <v-app light class="contents">

    <div class="text-xs-center">
      <v-pagination
        v-model="$page.current"
        v-bind:length="$page.total"
        v-bind:total-visible="$page.visible"
      ></v-pagination>
    </div>

    <div class="text-xs-center">
      <v-pagination
        v-model="$page.current"
        v-bind:length="$page.total"
        v-bind:total-visible="$page.visible"
        prev-icon="mdi-menu-left"
        next-icon="mdi-menu-right"
        dark
      ></v-pagination>
    </div>

  </v-app>
</template>

<script>
  import Vue from 'vue';
  import Pagination from '@/plugins/pagination.js'
  Vue.use(Pagination);

  export default {
    name: 'ArticleList',
    data () {
      return {
        list: []
      }
    },
    created() {
      this.list = [
        {id: 1, title: 'hoge', description: 'text'},
        {id: 2, title: 'hoge', description: 'text'},
        {id: 3, title: 'hoge', description: 'text'},
                           .
                           .
                           .
        {id:38, title: 'hoge', description: 'text'},
        {id:39, title: 'hoge', description: 'text'},
        {id:40, title: 'hoge', description: 'text'}
      ];
    },
    mounted() {
      this.$page.current = this.$route.query.page; // URLのクエリの値をセット
      this.$page.rowsPerPage = 5;                  // 1ページに表示する件数
      this.$page.rows = this.list.length;          // 総件数
    },
    watch: {
      /**
       * ページ番号の変化を監視
       */
      '$page.current': function (newNumber) {
        // ページ番号が変わったら、URLのクエリの値も変更する
        this.$router.push({name: this.name, query: {page: newNumber}})
      }
    },
  }
</script>
```

## テスト
動かしてみる

**ページ数が多い場合)**
![sample1.png](https://qiita-image-store.s3.amazonaws.com/0/142279/46023297-db51-9de3-93e3-46db63ef7c41.png)

**ページ数が少ない場合)**
![sample2.png](https://qiita-image-store.s3.amazonaws.com/0/142279/9a4fe079-5df4-fca4-785c-c1d5841b6efa.png)

まあ、とりあえず動きました。

## 参考サイト
* [Vuetify - Pagination](https://vuetifyjs.com/ja/components/paginations)
* [vue-router + apollo + vuetify でページネーションを作る](https://qiita.com/ryo2132/items/e494cd7bc94e82e9d4d9)
* [Vue.jsでページ番号付きのページネーションをつくる](https://kuroeveryday.blogspot.com/2015/07/Vuejs-PaginationWithPageNumber.html)