Good afternoon folks,
I have an unordered list that I would like to apply pagination with flexboxes. Any help is highly appreciated:
> <template>
<div id="app">
<ul>
<li v-for="item in items.results" :key="item.id">
{{ item.pub_date }} {{item.image.file}} {{item.title}}
<div >
<span
v-for="downloadable in item.downloadable.filter(d => !!d.document_en)"
:key="downloadable.id"
>{{ downloadable.document_en.file }}</span>
</div>
</li>
</ul>
</div>
</template>
<style>
</style>
CodePudding user response:
That's pretty much state forward.
Create few constants:
const ROW_PER_PAGE = 10;
const CURRENT_PAGE = 0;
add them in your data method:
return {
rowPerPage: ROW_PER_PAGE,
currentPage: CURRENT_PAGE,
items: allMyData
}
use computed
property to return only the required number of rows:
computed: {
getPaginatedData() {
const start = this.currentPage * this.rowPerPage;
const end = start this.rowPerPage;
return this.items.slice(start, end); // end index won't be included
}
}
Now simply use this getPaginatedData
in your template
<li v-for="item in getPaginatedData" :key="item.id">
The last piece is have buttons to change the page. And on each page change, simply update the currentPage
var.
For adding pagination buttons, ofcourse you can create your own component, but if you are less on time then you may use per-developed component. The one which I like is https://getbootstrap.com/docs/4.0/components/pagination/
CodePudding user response:
Step 1: Create Pagination.vue
component
<template>
<ul >
<li >
<button type="button" @click="onClickFirstPage" :disabled="isInFirstPage">First</button>
</li>
<li >
<button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage">Previous</button>
</li>
<li :key="page.id" v-for="page in pages" >
<button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled"
:>{{ page.name }}</button>
</li>
<li >
<button type="button" @click="onClickNextPage" :disabled="isInLastPage">Next</button>
</li>
<li >
<button type="button" @click="onClickLastPage" :disabled="isInLastPage">Last</button>
</li>
</ul>
</template>
<script>
export default {
name: 'pagination',
props: {
maxVisibleButtons: {
type: Number,
required: false,
default: 3
},
totalPages: {
type: Number,
required: true
},
perPage: {
type: Number,
required: true
},
currentPage: {
type: Number,
required: true
}
},
computed: {
isInFirstPage () {
return this.currentPage === 1
},
isInLastPage () {
if (this.totalPages === 0) {
return true
}
return this.currentPage === this.totalPages
},
startPage () {
// When on the first page
if (this.currentPage === 1) {
return 1
}
// When on the last page
if (this.totalPages < this.maxVisibleButtons) {
return 1
}
if (this.currentPage === this.totalPages) {
return this.totalPages - this.maxVisibleButtons 1
}
// When in between
return this.currentPage - 1
},
endPage () {
if (this.totalPages === 0) {
return 1
}
if (this.totalPages < this.maxVisibleButtons) {
return this.totalPages
}
return Math.min(this.startPage this.maxVisibleButtons - 1, this.totalPages)
},
pages () {
const range = []
for (let i = this.startPage; i <= this.endPage; i = 1 ) {
range.push({
name: i,
isDisabled: i === this.currentPage
})
}
return range
}
},
methods: {
onClickFirstPage () {
this.$emit('pagechanged', 1)
},
onClickPreviousPage () {
this.$emit('pagechanged', this.currentPage - 1)
},
onClickPage (page) {
this.$emit('pagechanged', page)
},
onClickNextPage () {
this.$emit('pagechanged', this.currentPage 1)
},
onClickLastPage () {
this.$emit('pagechanged', this.totalPages)
},
isPageActive (page) {
return this.currentPage === page
}
}
}
</script>
<style scoped>
.pagination {
list-style-type: none;
float: right;
margin: 10px 0;
}
.pagination-item {
display: inline-block;
}
.active {
background-color: #943849;
color: #ffffff !important;
font-weight: bold;
}
button[disabled], html input[disabled] {
cursor: default;
color: lightgray;
}
</style>
Step 2: Add Pagination
component reference in app.vue
component
import Pagination from './components/Pagination'
Add Pagination
component in app.vue
export default {
components: {
Pagination,
},
Step 3: Create model data with pagination object
data() {
return {
items:[],
page: 1,
totalPages: 0,
totalRecords: 0,
recordsPerPage: 10
}
},
Step 4: Create an methods
for load data
and adding pagination
methods: {
loadPressRelease () {
this.showLoader = true
axios.get(`https://zbeta2.mykuwaitnet.net/backend/en/api/v2/media-center/press-release/?page=${this.page}&page_size=${this.recordsPerPage}&type=5`)
.then(response => {
this.showLoader = false
this.items = response.data
this.totalPages = Math.ceil(response.data.count / this.recordsPerPage)
this.totalRecords = response.data.count
})
},
onPageChange(page) {
this.page = page
this.loadPressRelease()
}
}
Step 5: Default page load on created
methods
created() {
this.loadPressRelease()
},
Step 6: HTML
template with pagination
reference
<div id="app">
<ul>
<li v-for="item in items.results" :key="item.id">
{{ item.pub_date }} {{item.image && item.image.file}} {{item.title}}
<div >
<span v-for="downloadable in item.downloadable.filter(d => !!d.document_en)"
:key="downloadable.id">{{ downloadable.document_en.file }}
</span>
</div>
</li>
</ul>
<Pagination v-if="items.results" :total-pages="totalPages" :per-page="this.recordsPerPage" :current-page="page" @pagechanged="onPageChange" />
</div>