Pagination with vue2.x
by bc_rikko
HTML
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<div id="app" class="container">
<nav>
<ul class="pagination">
<li class="page-item">
<a @click="first" class="page-link" href="#">«</a>
</li>
<li class="page-item">
<a @click="prev" class="page-link" href="#"><</a>
</li>
<li class="page-item" v-for="i in displayPageRange" :class="{active: i-1 === currentPage}">
<a @click="pageSelect(i)" class="page-link" href="#">{{ i }}</a>
</li>
<li class="page-item">
<a @click="next" class="page-link" href="#">></a>
</li>
<li class="page-item">
<a @click="last" class="page-link" href="#">»</a>
</li>
</ul>
</nav>
<ul class="list-group">
<li v-for="item in displayItems" class="list-group-item">
{{ item.text }}
</li>
</ul>
</div>
JavaScript
new Vue({
el: "#app",
data () {
return {
currentPage: 0, // 現在のページ番号
size: 10, // 1ページに表示するアイテムの上限
pageRange: 10, // ページネーションに表示するページ数の上限
items: [] // 表示するアイテムリスト
}
},
mounted () {
// 表示するアイテムの初期化(APIで取得するなど)
this.items = [...Array(200)].map((_, i) => {
return {
text: `Item: ${i}`
};
});
},
computed: {
/**
* ページ数を取得する
* @return {number} 総ページ数(1はじまり)
*/
pages () {
return Math.ceil(this.items.length / this.size);
},
/**
* ページネーションで表示するページ番号の範囲を取得する
* @return {Array<number>} ページ番号の配列
*/
displayPageRange () {
const half = Math.ceil(this.pageRange / 2);
let start, end;
if (this.pages < this.pageRange) {
// ページネーションのrangeよりページ数がすくない場合
start = 1;
end = this.pages;
} else if (this.currentPage < half) {
// 左端のページ番号が1になったとき
start = 1;
end = start + this.pageRange - 1;
} else if (this.pages - half < this.currentPage) {
// 右端のページ番号が総ページ数になったとき
end = this.pages;
start = end - this.pageRange + 1;
} else {
// activeページを中央にする
start = this.currentPage - half + 1;
end = this.currentPage + half;
}
let indexes = [];
for (let i = start; i <= end; i++) {
indexes.push(i);
}
return indexes;
},
/**
* 現在のページで表示するアイテムリストを取得する
* @return {any} 表示用アイテムリスト
*/
displayItems () {
const head = this.currentPage * this.size;
return this.items.slice(head, head + this.size);
},
/**
* 現在のページかどうか判定する
* @param {number} page ページ番号
* @return {boolean} 現在のページならtrue
*/
isSelected (page) {
return page - 1 === this.currentPage;
}
},
methods: {
/**
* ページ先頭に移動する
*/
first () {
this.currentPage = 0;
this.selectHandler();
},
/**
* ページ後尾に移動する
*/
last...