How to use vue-bootstrap to paginate a list of items.
By: Nick Gottschlich
Tags: Web Development, Vue, Bootstrap Vue, Pagination, Front End

Often times while developing an application, you will have a lot of data to show to the user. Showing it all on one screen is one option, but that can cause a whole lot of vertical scrolling for the user, and can hurt performance depending on how much data you are dealing with. Pagination may be a better option.

So let’s say you’ve set up your own app with Vue and Bootstrap-Vue, and you want to use Bootstrap-Vue’s excellent Pagination component. But wait, Bootstrap-Vue’s docs only show you how to do that in concordance with the Bootstrap-Vue table component! What if we want to use it with a simple list of values instead? Never fear, that’s what this blog post is all about.

So let’s take a look at some example data that we want to display in a paginated list:

data = [

{

header: 'item 1',

text: '❤️',

id: 1,

},

{

header: 'item 2',

text: '🗿',

id: 2,

},

{

header: 'item 3',

text: '⛺️',

id: 3,

},

{

header: 'item 4',

text: '🌄',

id: 4,

},

{

header: 'item 5',

text: '💎',

id: 5,

},

{

header: 'item 6',

text: '⏳',

id: 6,

},

{

header: 'item 7',

text: '🧱',

id: 7,

},

];

To do this without any pagination, we can build out a simple Vue component like so:

<template>

<div>

<ul>

<li v-for="item in itemsForList" :key="item.id">

<h1>{{item.header}}</h1>

<span>{{item.text}}</span>

</li>

</ul>

</div>

</template> <script lang="ts">

import { Component, Vue } from 'vue-property-decorator'; @Component

export default class HelloWorld extends Vue {

data = [

{

header: 'item 1',

text: '❤️',

id: 1,

},

{

header: 'item 2',

text: '🗿',

id: 2,

},

{

header: 'item 3',

text: '⛺️',

id: 3,

},

{

header: 'item 4',

text: '🌄',

id: 4,

},

{

header: 'item 5',

text: '💎',

id: 5,

},

{

header: 'item 6',

text: '⏳',

id: 6,

},

{

header: 'item 7',

text: '🧱',

id: 7,

},

];

}

</script> export default class HelloWorld extends Vue {data = [header: 'item 1',text: '❤️',id: 1,},header: 'item 2',text: '🗿',id: 2,},header: 'item 3',text: '⛺️',id: 3,},header: 'item 4',text: '🌄',id: 4,},header: 'item 5',text: '💎',id: 5,},header: 'item 6',text: '⏳',id: 6,},header: 'item 7',text: '🧱',id: 7,},];

Here’s how it looks:

It’s beautiful! 😍

Great! Now let’s get to work with the Pagination component. We can introduce in the html like so:

<b-pagination

v-model="currentPage"

:total-rows="rows"

:per-page="perPage"

aria-controls="itemList"

align="center"

></b-pagination>

What are all these values? To make sense of this, we can reference what the Pagination component looks like:

v-model refers to whatever page the user is currently on. We can default it to 1 in our code like so: currentPage = 1 .

total-rows is, well, the total number of rows. We get that in our code by referencing the length of our data object, rows = this.data.length .

per-page is how many items we would like to show per page, we can set that by doing perPage = 3

aria-controls helps set up accessibility controls on our Pagination component, we can set that up on our list by doing <ul id=”itemList”> .

And finally align="center" just aligns the component to the center of the page.

So we are almost ready, last thing we have to do is get the right items to show in each list. We do a little slicing and dicing on the data to make that happen:

get itemsForList() {

return this.data.slice(

(this.currentPage - 1) * this.perPage,

this.currentPage * this.perPage,

);

}

currentPage will get updated each time a new page is clicked in the Pagination component, so the data sliced will get recomputed to grab only the values needed for that page.

Okay, put this all together and we have our whole file!

<template>

<div>

<b-pagination

v-model="currentPage"

:total-rows="rows"

:per-page="perPage"

aria-controls="itemList"

align="center"

></b-pagination>

<ul id="itemList">

<li v-for="item in itemsForList" :key="item.id">

<h1>{{item.header}}</h1>

<span>{{item.text}}</span>

</li>

</ul>

</div>

</template> <script lang="ts">

import { Component, Vue } from 'vue-property-decorator'; @Component

export default class HelloWorld extends Vue {

currentPage = 1; export default class HelloWorld extends Vue {currentPage = 1; perPage = 3; data = [

{

header: 'item 1',

text: '❤️',

id: 1,

},

{

header: 'item 2',

text: '🗿',

id: 2,

},

{

header: 'item 3',

text: '⛺️',

id: 3,

},

{

header: 'item 4',

text: '🌄',

id: 4,

},

{

header: 'item 5',

text: '💎',

id: 5,

},

{

header: 'item 6',

text: '⏳',

id: 6,

},

{

header: 'item 7',

text: '🧱',

id: 7,

},

]; rows = this.data.length; get itemsForList() {

return this.data.slice(

(this.currentPage - 1) * this.perPage,

this.currentPage * this.perPage,

);

}

}

</script>

And how does it look in action?

😲

Here is a github repo where you can test the code yourself!

And that’s it! Go forth and paginate!