Dynamic Pagination With Vue.js
Learn how to set up dynamic pagination using Vue.js and Nuxt.js. In this tutorial, we'll go over the code to set up a web page, then add dynamic pagination.
Join the DZone community and get the full member experience.
Join For FreeFor this tutorial, I will be using Atom.
- Download the Atom code editor.
- Install the Vue-fmt plugin if you do not see code being highlighted.
Firstly, What Is Vue.js?
Vue.js is a single page application JavaScript framework. It has many similarities to Angular and React. It is a progressive web application framework that is useful for developing more interactive web apps. Along with web applications, Vue.js is widely used by many websites like GitLab, 9gag, Behance, and many others.
What Is Nuxt.js?
Nuxt.js is a framework for Vue.js. It is mainly used for server-side rendering of Vue.js apps. As this is a framework for Vue.js, there are many similarities between Nuxt.js and Vue.js. You do not need to make many changes in your app if you are migrating from Vue.js to Nuxt.js. This hexadecimal to decimal page is an example of server-side rendered app.
Getting Started
Now, we can start developing the project. Developing dynamic pagination requires you to have basic knowledge of Vue.js and Nuxt.js. You should know the installation process and basic HTML, CSS, and router-links. I have to tell you that Vue.js has one of the best tutorials, you can visit here to learn more.
In this article, we have used w3schools’s CSS material. Copy and paste the following code if you are developing an app with Nuxt.js.
xxxxxxxxxx
script: [
{ src: 'https://code.jquery.com/jquery-3.4.1.slim.min.js', integrity: 'sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n', crossorigin: 'anonymous' },
{ src: 'https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js', integrity: 'sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo', crossorigin: 'anonymous' },
{ src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js', integrity: 'sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6', crossorigin: 'anonymous' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Oswald'},
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Open Sans'},
{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'},
{ rel: 'stylesheet', href: 'https://www.w3schools.com/w3css/4/w3.css'},
{ rel: 'stylesheet', href: 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css', integrity: 'sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh', crossorigin:'anonymous'},
{ rel: 'stylesheet', href: 'https://www.w3schools.com/lib/w3-theme-black.css'}
]
And in case you are using Vue.js then update index.html.
x
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://www.w3schools.com/lib/w3-theme-black.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
Let’s dive into the code,
The template tag contains all the basic HTML about laptops, RAM, operating system, and price, there is nothing “Vueish” about it except v-for
.
You can use the v-for
directive to render a list of items based on an array. The v-for directive requires “item in items,” in this case, the first v-for
directive is “pageNumber in totalPages” and another v-for
directive is “article in paginate,” which will get all the information about a laptop. When currentPage
is set to 1
, dynamic pagination will start from the first page. As soon as a user clicks on another page, currentPage
updates to the page number clicked by the user.
Template HTML:
x
<template lang="html">
<div class="w3-light-grey">
<div class="w3-content">
<div class="w3-row w3-padding w3-border">
<div class="w3-col l8 s12">
<div class="w3-container w3-white w3-margin w3-padding-large">
<div class="w3-justify">
<h1>Laptops</h1>
<br><br>
<div>
<button v-for="pageNumber in totalPages" :key="pageNumber.id" class="w3-button" v-bind:key="pageNumber" @click="setPage(pageNumber)" :class="{current: currentPage === pageNumber, last: (pageNumber == totalPages && Math.abs(pageNumber - currentPage) > 3), first:(pageNumber == 1 && Math.abs(pageNumber - currentPage) > 3)}">{
{
pageNumber
}
}
</button>
</div>
<div class="container w3-white w3-card" v-for="article in paginate" :key="article._id">
<br>
<div class="row">
<div class="col-sm-4">
<img src="~/assets/laptop.jpg">
</div>
<div class="col-sm-4">
<h5><span class="w3-large w3-text-teal">{
{ article.title
}
},</span></h5>
<span>OS: {{article.os}}</span><br>
<span>{{article.size}} Inches</span><br>
<span>{{article.ram}} GB RAM</span><br>
<span v-if="article.storage >= 1000">{
{ article.storage/1000
}
}
TB Storage,</span>
<span v-else>{
{
article.storage
}
} GB Storage,</span><br>
</div>
<div class="col-sm-4">
<h3>${
{
article.price
}
}</h3>
<p><a href=""><button class="w3-button w3-block w3-teal">Buy Now</button></a></p>
</div>
</div>
<hr>
</div>
<div>
<button v-for="pageNumber in totalPages" :key="pageNumber.id" class="w3-button" v-bind:key="pageNumber" @click="setPage(pageNumber)" :class="{current: currentPage === pageNumber, last: (pageNumber == totalPages && Math.abs(pageNumber - currentPage) > 3), first:(pageNumber == 1 && Math.abs(pageNumber - currentPage) > 3)}">{
{
pageNumber
}
}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Have a look at the following code, it is a data function with a return object which is used for two-way data binding. This object contains the articles
array, which has all the information about a laptop's operating system, price, weight, size, storage, and RAM. You can update itemsPerPage
to any number. If you want to show five items per page, then you can update that to 5
.
data()
{
return {
articles: [
{
os: 'Windows',
price: '500',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
},
{
os: 'Chromeos',
price: '400',
weight: '7.0 Pounds',
size: '11.1',
storage: '256 GB',
ram: '4',
company: 'hp',
title: 'HP Chromebook 14'
},
{
os: 'Windows',
price: '450',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
},
{
os: 'Windows',
price: '600',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
},
{
os: 'Windows',
price: '700',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
},
{
os: 'Windows',
price: '350',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
},
{
os: 'Windows',
price: '400',
weight: '3.9',
size: '11.1',
storage: '500',
ram: '8',
company: 'hp',
title: 'HP laptop 14'
}],
currentPage: 1,
itemsPerPage: 3,
resultCount: 0
}
},
Add the following code inside methods
. The setPage
function is called to update the current page.
xxxxxxxxxx
methods: {
setPage: function(pageNumber) {
this.currentPage = pageNumber
},
},
Here is the computed property. totalPage
is the logic for total dynamic pages. For example, if itemsPerPage
is 3
and there are a total of 12 items in the articles
array, then the totalPage
element will be 4
.
x
computed:
{
/* eslint-disable */
totalPages: function ()
{
if (this.resultCount == 0)
{
return 1
}
else
{
return Math.ceil(this.resultCount / this.itemsPerPage)
}
},
/* eslint-disable */
paginate: function ()
{
if (!this.articles || this.articles.length != this.articles.length)
{
return
}
this.resultCount = this.articles.length
if (this.currentPage >= this.totalPages)
{
this.currentPage = this.totalPages
}
var index = this.currentPage * this.itemsPerPage - this.itemsPerPage
return this.articles.slice(index, index + this.itemsPerPage)
}
},
}
Add some styling to change the color of the current page.
xxxxxxxxxx
<style lang="css">
.current {
color: teal;
}
</style>
And that’s a wrap! After implementing this code, if you have any doubts then do not hesitate to reach us by dropping a comment below.
Opinions expressed by DZone contributors are their own.
Comments