DEV Community

Mallaya
Mallaya

Posted on • Edited on

Develop Dynamic Pagination in Vue.js/Nuxt.js

To develop a dynamic pagination requires you to have basic knowledge about Vue.js and Nuxt.js. You need to have Vue.js or Nuxt.js installed on your computer. Along with that, you need to have a basic knowledge about HTML, CSS, and router-links. I have to tell you that Vue.js has one of the best tutorials.

In this article, we have used w3schools’ CSS material. If you are developing an app with Nuxt.js then you need to add the following code in your Nuxt.config.js file.

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'}
    ]

Enter fullscreen mode Exit fullscreen mode

And in case you are using Vue.js then update index.html file which is placed at the root.

<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">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
Enter fullscreen mode Exit fullscreen mode

Before starting, there are a few Vue.js properties that you need to remember:

Two-way data-binding:

Two-way data binding can be performed with the help of the v-model. You can use the V-model directive to store the values from HTML and you can use that value further in any method. All the v-model values change in real-time, a server does not reload for these directives.

Methods:

Methods are the actions that can be performed on a different object. Here, we are going to use the method to setpage on the button click event.

Computed Property:

In this tutorial, we are going to use computed property heavily. A computed property is used to describe a value that depends on another value. It makes Vue know when to update DOM. For example, in this dynamic pagination, every value depends on the previous value. The current page’s color indirectly depends on the previous page and total pages.

In this tutorial, we have created a list of laptops with different specifications like RAM, Price, storage, operating system, and laptop size. If The following code is going to be the same for both Nuxt.js and Vue.js. We are going to use just one Vue file and you can use the following code to create dynamic pagination.

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 1, the 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:

<template lang="html">
  <div class="w3-light-grey">
<div class="w3-content" style="max-width:1600px">
  <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" style="width:100px; height:100px">
    </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>

Enter fullscreen mode Exit fullscreen mode

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 operating system, price, weight, size, storage, and laptop ram. You can update “itemsPerPage” to any number. If you want to show five items per page, then you can update that to five.

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
  }
},
Enter fullscreen mode Exit fullscreen mode

Add the following code inside the methods. “setpage” function is called to update the current page.

methods: {
setPage: function(pageNumber) {
    this.currentPage = pageNumber
  },
},
Enter fullscreen mode Exit fullscreen mode

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 Article array then “totalPage” element will be 4.

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)
      }
  },
}
Enter fullscreen mode Exit fullscreen mode

Add some styling to change the color of the current page.

<style lang="css">
.current {
color: teal;
}
</style>

Enter fullscreen mode Exit fullscreen mode

So, 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.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.