Paulund

Add Pagination To VueJS WordPress Theme

In this tutorial we're going to add previous and next pagination buttons to the Homepage and the Category page.

When using the WordPress REST API to get post you need to use an argument of page, this tells WordPress what page of posts to return from the query which is offset by the amount of posts per page.

Homepage Component

Therefore we need to change the Homepage component to accept any changes to the router querystring of page and append this to the end of the POST search URL. The method inside this component we need to change is the getPosts() method. We can access all the querystrings in the URL by using the $route object, with the query property.

this.$route.query.page

This now changes the method to the below code.


  methods: {
    getPosts () {
      let postsUrl = process.env.API_URL + '/wp-json/wp/v2/posts'

      if (this.$route.query.page !== undefined) {
        postsUrl += '?page=' + this.$route.query.page
      }

      axios.get(postsUrl)
      .then(response => {
        this.posts = response.data
      })
      .catch(e => {
        console.log(e)
      })
    }
  },

Homepage commit

Category Component

The Category component also has a getPosts() method and will need to have the same change to the search URL by appending the querystring page onto the end of the URL.


    getPosts () {
      let postsUrl = process.env.API_URL + '/wp-json/wp/v2/posts?categories=' + this.category.id

      if (this.$route.query.page !== undefined) {
        postsUrl += '&page=' + this.$route.query.page
      }

      axios.get(postsUrl)
      .then(response => {
        this.posts = response.data
      })
      .catch(e => {
        console.log(e)
      })
    }

Category Component

List Post Component

Both the Homepage and the Category page use the list post component, therefore we can change only this component with the pagination changes which will affect both pages. First, we need to add the buttons in the HTML, this can go under the for loop for the list posts. We need to add additional code to change both the link and the click event that happens when we click on either previous or next buttons.


<nav class="pagination">
  <router-link :to="previousRoute" class="pagination-previous" v-on:click.native="previousClick">Previous</router-link>
  <router-link :to="nextRoute" class="pagination-next" v-on:click.native="nextClick">Next</router-link>
</nav>

We will need to change the page parameter so we need to keep track of what the current page is, which means we can add a currentPage data point to the component.


  data () {
    return {
      currentPage: 1
    }
  },

On the created event of the component, we need to get the querystring page parameter and use this to override the currentPage data point.


  created () {
    if (this.$route.query.page > 1) {
      this.currentPage = parseInt(this.$route.query.page)
    }
  },

We need to create 4 computed functions that will react to querystring parameter change and edit the routes and the click events. We need to functions for previousRoute, nextRoute, previousClick and nextClick. The previous route needs to change the querystring page property by taking off one from the currentPage.

The next route will need to change the querystring page property to add one to the currentPage.

The previous click function will change the data point of currentPage and remove one from its value, then it will call the parent component's getPosts() method. The next click function will change the data point of the currentPage and add one to its value, then call the parent component's getPosts() method. I've also added window.scrollTo(0, 0) to the bottom of both click event this will just reset the scrollbar to the top of the page, this is optional but it's a nice way of showing the users the content has changed.


computed: {
    previousRoute () {
      let route = {}

      route['name'] = this.$route.name

      if (this.currentPage > 1) {
        route['query'] = { page: this.currentPage - 1 }
      }

      return route
    },

    nextRoute () {
      let route = {}

      route['name'] = this.$route.name
      route['query'] = { page: this.currentPage + 1 }

      return route
    },

    previousClick () {
      if (this.currentPage > 1) {
        this.currentPage = this.currentPage - 1
      }

      this.$parent.getPosts()
      window.scrollTo(0, 0)
    },

    nextClick () {
      this.currentPage = this.currentPage + 1

      this.$parent.getPosts()
      window.scrollTo(0, 0)
    }
  },

You can see the full code change to the list post component in the link below. List Post Component