Back to Course |
Vue.js 3 + Laravel 11 + Vite: SPA CRUD

Pagination with External Vue Package

Loading the whole list of data into a table isn't logical, especially if you can hundreds or thousands of records. This is where the pagination comes in. In this lesson, we will add pagination to the posts table using the laravel-vue-pagination package.

finished vue pagination


First, of course, we need to install the package.

npm install laravel-vue-pagination

Next, instead of just calling all posts in the Controller, we need to paginate them.

app/Http/Controllers/Api/PostController.php:

class PostController extends Controller
{
public function index()
{
return PostResource::collection(Post::all());
return PostResource::collection(Post::paginate(10));
}
}

Next, in the PostsIndex Vue component, in the v-for, we need to change posts to posts.data instead.

resources/js/components/Posts/Index.vue:

<template>
// ...
<tr v-for="post in posts">
<tr v-for="post in posts.data">
// ...
</template>

Then our posts variable in the Composable needs to become an object instead of array.

resources/js/composables/posts.js:

import { ref } from 'vue'
 
export default function usePosts() {
const posts = ref([])
const posts = ref({})
 
const getPosts = async () => {
axios.get('/api/posts')
.then(response => {
posts.value = response.data.data;
})
}
 
return { posts, getPosts }
}

Next, we need to set a page parameter to the getPosts. Also, set that page as a parameter to the URL. And we don't need to return the data result. We will return the full API response.

resources/js/composables/posts.js:

import { ref } from 'vue'
 
export default function usePosts() {
const posts = ref({})
 
const getPosts = async () => {
axios.get('/api/posts')
const getPosts = async (page = 1) => {
axios.get('/api/posts?page=' + page)
.then(response => {
posts.value = response.data.data;
posts.value = response.data;
})
}
 
return { posts, getPosts }
}

Now we need to add pagination links below the table.

To do that, we also need to import the package in the PostsIndex Vue component.

Because we are using Tailwind for the design, we will import the Tailwind version, but if you need there is also a Bootstrap version. Or you may use a renderless pagination and style it yourself.

resources/js/components/Posts/Index.vue:

<template>
<div class="overflow-hidden overflow-x-auto p-6 bg-white border-gray-200">
<div class="min-w-full align-middle">
<table class="min-w-full divide-y divide-gray-200 border">
// ...
</table>
 
<TailwindPagination :data="posts" @pagination-change-page="getPosts" class="mt-4" />
</div>
</div>
</template>
 
<script setup>
import { onMounted } from "vue";
import { TailwindPagination } from 'laravel-vue-pagination';
import usePosts from "@/composables/posts";
 
const { posts, getPosts } = usePosts()
onMounted(() => {
getPosts()
})
</script>

Now we have a working pagination.

vue pagination