Kendo UI for Vue makes pagination simple with the Pager component. Let’s see how to use it.
There are many types of websites that fetch and display some kind of data to users—for instance, blog articles, recipes, news and so on. A website can have thousands of records in a database that could be displayed to its users. However, it would be very inefficient to fetch and show everything. That’s why, usually, data is fetched in chunks and then displayed using techniques, such as pagination or infinite scroll.
In this article, we will cover how to implement client-side pagination with Kendo UI for Vue.
You can find the full code example in this GitHub repo. Below you can also find an interactive StackBlitz example.
We are going to use Vite to quickly scaffold a new Vue project. If you haven’t heard about Vite before, you might want to check out one of my articles about it—What Is Vite: The Guide to Modern and Super-Fast Project Tooling.
Run the command below in your terminal to create a new react project.
$ npm init vite kendo-vue-data-table-pagination -- --template vue
After the project creation is complete, run the following commands to get into the project directory and install all dependencies.
$ cd kendo-vue-data-table-pagination && npm install
Finally, you can start the development server by running the npm run dev
command.
You should see the project running upon visiting localhost:3000
in your browser. Next, let’s install all Kendo libraries we will need for this project.
$ npm install --save @progress/kendo-vue-data-tools @progress/kendo-vue-intl @progress/kendo-vue-buttons @progress/kendo-vue-dropdowns @progress/kendo-vue-inputs @progress/kendo-vue-dateinputs @progress/kendo-drawing @progress/kendo-data-query @progress/kendo-theme-default @progress/kendo-licensing
After the installation is complete, let’s clean up the App
component and its styles file. Replace the contents of the App.vue
file with the code below.
src/App.vue
<template>
<div :id="$style.app">
<h1>Posts</h1>
</div>
</template>
<script setup></script>
<style module>
#app {
text-align: center;
color: #2c3e50;
max-width: 1180px;
margin: 50px auto;
}
</style>
Lastly, let’s import the Kendo theme in the main.js
file.
src/main.js
import { createApp } from 'vue';
import '@progress/kendo-theme-default/dist/all.css';
import App from './App.vue';
createApp(App).mount('#app');
That’s it for the initial setup.
Before adding pagination functionality, we actually need to have some data to paginate first. For demonstration purposes, we will use the jsonplaceholder API to fetch a list of posts that we can then paginate.
src/App.vue
<template>
<div :id="$style.app">
<h1>Posts</h1>
<table class="k-table k-table-layout-fixed">
<thead class="k-table-thead">
<tr class="k-table-row">
<th class="k-table-th">Post ID</th>
<th class="k-table-th">User ID</th>
<th class="k-table-th">Title</th>
<th class="k-table-th">Excerpt</th>
</tr>
</thead>
<tbody class="k-table-tbody">
<tr class="k-table-row" v-for="post of allPosts" :key="post.id">
<td class="k-table-td">{{ post.id }}</td>
<td class="k-table-td">{{ post.userId }}</td>
<td class="k-table-td">{{ post.title }}</td>
<td class="k-table-td">{{ post.excerpt?.slice(0, 50) }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
const allPosts = ref([]);
fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(json => {
allPosts.value = json.map(item => {
return {
...item,
excerpt: item.body.slice(0, 50),
};
});
});
</script>
<style module>
#app {
text-align: center;
color: #2c3e50;
max-width: 1180px;
margin: 50px auto;
}
</style>
We fetch a list of posts, which are set on the allPosts
ref. In the template
, a table with four columns is rendered—Post ID
, User ID
, Title
and Excerpt
. The jsonplaceholder
API returns 100 posts; therefore, if you have a look at the website now, you will see that the table is quite big. Let’s handle it by utilizing the Pager
component offered by Kendo UI for Vue.
src/App.vue
<template>
<div :id="$style.app">
<h1>Posts</h1>
<table class="k-table k-table-layout-fixed">
<thead class="k-table-thead">
<tr class="k-table-row">
<th class="k-table-th">Post ID</th>
<th class="k-table-th">User ID</th>
<th class="k-table-th">Title</th>
<th class="k-table-th">Excerpt</th>
</tr>
</thead>
<tbody class="k-table-tbody">
<tr class="k-table-row" v-for="post of posts" :key="post.id">
<td class="k-table-td">{{ post.id }}</td>
<td class="k-table-td">{{ post.userId }}</td>
<td class="k-table-td">{{ post.title }}</td>
<td class="k-table-td">{{ post.excerpt?.slice(0, 50) }}</td>
</tr>
</tbody>
</table>
<div class="k-mt-8">
<Pager
:skip="skip"
:take="take"
:total="allPosts.length"
:buttonCount="5"
type="numeric"
:pageSizes="[5, 10, 20]"
info
previousNext
@pagechange="onPageChange"
/>
</div>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
import { Pager } from "@progress/kendo-vue-data-tools";
const skip = ref(0);
const take = ref(10);
const allPosts = ref([]);
const posts = computed(() =>
allPosts.value.slice(skip.value, skip.value + take.value)
);
fetch("https://jsonplaceholder.typicode.com/posts")
.then(response => response.json())
.then(json => {
allPosts.value = json.map(item => {
return {
...item,
excerpt: item.body.slice(0, 50),
};
});
});
const onPageChange = event => {
skip.value = event.skip;
take.value = event.take;
};
</script>
<style module>
#app {
text-align: center;
color: #2c3e50;
max-width: 1180px;
margin: 50px auto;
}
</style>
Let’s digest what exactly is happening. After imports, we have three refs and one computed prop.
const skip = ref(0);
const take = ref(10);
const allPosts = ref([]);
const posts = computed(() =>
allPosts.value.slice(skip.value, skip.value + take.value)
);
The skip
and take
values are used by the Pager
component to figure out the current page. For example, if skip
is set to 0
and take
equals 10
, then the first page
will be displayed. If skip
would be 30
, then the Pager
would be on the fourth page.
The allPosts
ref will store all posts fetched from the jsonplaceholder
API. The posts
computed utilizes the skip
and take
values to get only a subset of data for the page we are on.
Further, we have the code to fetch the posts and the onPageChange
method that is passed to the Pager
component. We use it to update skip
and take
refs.
const onPageChange = event => {
skip.value = event.skip;
take.value = event.take;
};
Finally, the Pager
component receives a few props. We already covered what skip
, take
and pageChange
do, so let’s focus on the rest of the props:
total
– The total number of items to paginate through.buttonCount
– The number of page buttons that should be displayed.pageSizes
– An array with numbers that specify options for items per page dropdown. Providing the [5, 10, 20]
array will allow users to change the number of items displayed.type
– The Pager
component supports two different types—numeric
and input
. Passing the numeric
type will result in the Pager
component using buttons for page
numbers. On the other hand, passing the input
type will replace page buttons with an input field.info
– Indicates whether the Pager
should display how many items out of the total are currently displayed.previousNext
– Configured whether previous and next buttons should be displayed.<Pager
:skip="skip"
:take="take"
:total="allPosts.length"
:buttonCount="5"
:pageSizes="[5, 10, 20]"
type="numeric"
info
previousNext
@pagechange="onPageChange"
/>
That’s it. If you visit the website, you should see that we now have a working table with pagination!
The Pager
component offered by Kendo UI for Vue is a useful tool to quickly implement client-side pagination. Besides being easy to use, it is also responsive, so it can be used in any project. Kendo UI for Vue is a great choice since it offers many feature-rich and production-ready components that can speed up development tremendously.
Thomas Findlay is a 5-star rated mentor, full-stack developer, consultant, technical writer and the author of “React - The Road To Enterprise” and “Vue - The Road To Enterprise.” He works with many different technologies such as JavaScript, Vue, React, React Native, Node.js, Python, PHP and more. Thomas has worked with developers and teams from beginner to advanced and helped them build and scale their applications and products. Check out his Codementor page, and you can also find him on Twitter.