目次
はじめに
半年前にクライアント用に、Vue.jsでフィルター付きリストページを作りました。
幸いにしてクライアントが良く使ってくれているようで、データ量が増大していきました。
開発当初は、1秒も掛からなかったページの表示(レンダリング)が、2秒、3秒とだんだん遅くなっていきました。
これはまずいと思い、ページネーションを実装することにしました。
-
参考「vuejs-paginate」を使ってページネーションを実装する
「vuejs-paginate」は、ページネーションを実装するライブラリです。シンプルなAPIで提供されており、容易に実装することができます。CSSによってページネーションコンポーネントのスタイルをカスタマイズすることができます。コピペで実装できるサンプルを公開してます。
続きを見る
しかし、1つ問題がありました。
ページネーション付きのリストにフィルター機能を付属するにはどうしたら良いのだろう?
というわけで試しに作ってみました。
検証環境
Vue.js | 2.6.0 |
vuejs-paginate
|
2.1.0 |
導入手順
外部ファイル
サンプルにBootstrapベースのCSSで、ページネーションにvuejs-paginateを使用します。
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script> <script src="https://unpkg.com/[email protected]"></script>
HTML
リストを <table>
で準備します。
<paginate>
を設置してページネーションを用意します。
<div id="app"> <h2>page {{currentPage}}</h2> <div>search: <input type="text" v-model="select" placeholder="ID search"></div> <table class="table table-bordered"> <thead> <tr> <th>No</th> <th>Title</th> </tr> </thead> <tbody> <tr v-for="item in getLists"> <td>{{item.id}}</td> <td>{{item.title}}</td> </tr> </tbody> </table> <paginate v-model="currentPage" :page-count="getPageCount" :initial-page="4" :page-range="3" :margin-pages="2" :prev-text="'<'" :next-text="'>'" :container-class="'pagination'" :page-class="'page-item'"> </paginate> </div>
スクリプト
今回の一番重要なポイントは、フィルターの入力をされた時にwatchにて検知することです。
検知した際にページネーションの現在のページを1ページ目に変更しています。
これをしないと、現在ページだけ置いてけぼりになってしまいます。
var items = []; for(var i=1; i<=105; i++){ items.push({ id: i, title: 'item-'+i }); } Vue.component('paginate', VuejsPaginate); new Vue({ el: '#app', data: { select: '', items: items, parPage: 10, currentPage: 1 }, computed: { getItems: function() { let self = this; return this.items.filter(function(item){ return String(item.id).indexOf(self.select) !== -1; }); }, getLists: function(){ let current = this.currentPage * this.parPage; let start = current - this.parPage; return this.getItems.slice(start, current); }, getPageCount: function() { return Math.ceil(this.getItems.length / this.parPage); } }, watch:{ select: function(){ this.currentPage = 1; } } });
サンプル
最後に
フィルター機能付きのテーブルにページネーションを付ける方法でした。
今日はこの辺でー