目次
はじめに
半年前にクライアント用に、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;
}
}
});
サンプル
最後に
フィルター機能付きのテーブルにページネーションを付ける方法でした。
今日はこの辺でー