Laravel Vuejs Custom Server Side Pagination Tutorial Example

Throughout this Laravel Vue js custom pagination example tutorial, you will see and understand how to build or create server side pagination in vuejs and laravel application. This example show you step by step guide for make pagination in a Vue.js app with existing API (Server Side pagination) using Axios and bootstrap.

Laravel Vue Js Custom Pagination Example

Follow the following step by step guide on how to make custom server side pagination in laravel and vuejs application.

  • Step 1: Install Laravel App
  • Step 2: Connect Database to App
  • Step 3: Create Api controller
  • Step 4: Updates Routes
  • Step 5: Generate Dummy Records for Testing
  • Step 6: Install Laravel Vue UI
  • Step 7: Initiate Vue in Laravel
  • Step 8: Create Components
  • Step 9: Create Vue Routes
  • Step 10: Define Vue in App.js
  • Step 11: Run your Application

Install Laravel App

Open terminal further run below command to manifest a new laravel project, ignore this step if project is already installed:

composer create-project laravel/laravel laravel-vue-pagination

Connect Database to App

This step explains how to make database connection by adding database name, username and password in .env config file of your project:

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=#your database name
DB_USERNAME=#database username
DB_PASSWORD=#database password

Create Api controller

You need to create the user controller and define the server side pagination method:

php artisan make:controller Api/UserController

Controller is the quintessential file in Laravel application development. So, without further insert the given below code in UserController.php file.

app\Http\Controllers\Api\UserController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;

class UserController extends Controller
{
    public function index()
    {
        $users = User::orderBy('id', 'desc')->paginate(5);

        return response()->json($users, 200);
    }
}

Update Routes

Now, we will define API routes. Go to routes/api.php file and declare the foundational code.

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\UserController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/users', [UserController::class, 'index']);

Open routes/web.php file, in here; you have to define the following route:

routes\web.php

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('{any}', function () {
    return view('welcome');
})->where('any', '.*');

Generate Dummy Records for Testing

First run the migration for generating users table in database:

php artisan migrate

Now run the below commands sequentially and generate fake records for testing the laravel vue server side pagination example:

php artisan tinker
User::factory()->count(50)->create()

You can see in your users table 50 records created.

Install Laravel Vue UI

Run composer command to install Vue UI in laravel, it will manifest vue laravel scaffold:

composer require laravel/ui
php artisan ui vue

After that, use the command to install the vue router and vue axios packages. These packages are used to consume Laravel CRUD APIs.

npm install vue-router vue-axios

Subsequently, execute the command to install npm packages:

npm install

The npm run watch command compiles the assets, not just that with run watch command you don’t fret about re-run the compiler over and over again.

Initiate Vue in Laravel

Now open resources/views/layout/app.blade.php file and put the below code on it.

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" value="{{ csrf_token() }}" />
    <title>Vue JS CRUD Operations in Laravel</title>
    <link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
</head>
<body>
    <div id="app"></div>
    <script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>

Create Components

Next, you have to add the router-view directive in app.vue file; this template will help invoke all the vue routes associated with the components.

So, create app.vue file in resources/js folder, put the below code in resources/js/app.vue file:

<template>
    <div class="container">
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <div class="collapse navbar-collapse">
                <div class="navbar-nav">
                    <router-link class="nav-item nav-link ml-3" to="/users">Users</router-link>
                </div>
            </div>
        </nav>
        <router-view> </router-view>
    </div>
</template>

Now create a global component named as pagination.vue inside your resouces/js/components:

So open resources\js\components\pagination.vue file and put the below code on it:

<template>
    <div class="pagination_block">
        <nav aria-label="Page navigation example">
            <ul class="pagination justify-content-center">
                <li class="page-item" :class="{disabled : pagination.prev_page_url == null}">
                    <button type="button" class="page-link" @click="pageURL(pagination.first_page_url)">&laquo;</button>
                </li>
                <li class="page-item" :class="{disabled : pagination.prev_page_url == null}">
                    <button type="button" class="page-link" @click="pageURL(pagination.prev_page_url)">Previous</button>
                </li>
                <li class="page-item" v-if="current_page -2 > 0 " >
                    <button type="button" class="page-link" @click="pageURL(pagination.path + '?page=' + (current_page - 2 ) )">{{ current_page - 2}}</button>
                </li>
                <li class="page-item" v-if="pagination.prev_page_url" >
                    <button type="button" class="page-link" @click="pageURL(pagination.prev_page_url)">{{ current_page - 1}}</button>
                </li>
                <li class="page-item">
                    <button type="button" class="page-link" :class="{current : pagination.current_page == current_page}">{{ current_page}}</button>
                </li>
                <li class="page-item" v-if="pagination.next_page_url" >
                    <button type="button" class="page-link" @click="pageURL(pagination.next_page_url)">{{ current_page + 1}}</button>
                </li>
                <li class="page-item" v-if="current_page + 2 <= last_page" >
                    <button type="button" class="page-link" @click="pageURL(pagination.path + '?page=' + (current_page + 2 ) )">{{ current_page + 2 }}</button>
                </li>
                <li class="page-item" :class="{disabled : pagination.next_page_url == null}">
                    <button type="button" class="page-link" @click="pageURL(pagination.next_page_url)">Next</button>
                </li>
                <li class="page-item" :class="{disabled : pagination.next_page_url == null}">
                    <button type="button" class="page-link" @click="pageURL(pagination.last_page_url)">&raquo;</button>
                </li>
            </ul>
        </nav>
    </div>
</template>
<script>
    export default {
        props: ['pagination', 'current_page', 'last_page'],
        methods: {
            pageURL(url) {
                this.$parent.pageURL(url);
            }
        }
    }
</script>

This global component work in your hole project common way.

Add code in resources/js/components/users.vue file; in here we are getting all data from database and deleting single product object from database through vue component.

<template>
    <div class="container">
        <h1 class="text-center">Users</h1>
        <div class="row">
            <div class="col-md-12">
                <table class="table">
                    <thead>
                    <tr>
                        <th>#</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Created At</th>
                        <th>Action</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(user, key) of users.data">
                            <td>{{ key+1 }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.email }}</td>
                        </tr>
                    </tbody>
                </table>
                <pagination
                    :pagination="users"
                    :current_page="users.current_page"
                    :last_page="users.last_page"
                ></pagination>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data () {
            return {
                users: {}
            }
        },
        created () {
            this.pageURL('api/users');
        },
        methods: {
            pageURL (url) {
                let vm = this;
                vm.loading = true;
                axios.get(url).then(({ data }) => {
                    vm.users = data;
                    vm.loading = false;
                })
                .catch((error) => {
                    vm.loading = false;
                    console.log(error);
                });
            }
        }
    }
</script>

Create Vue Routes

In this step, you have to create vue routes, create routes.js inside resources/js directory, add the code in the resources/js/routes.js file:

import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);

import Users from './components/dashboard/users.vue';
const routes = [
    {
        path: '/users',
        component: Users,
        name: "Users"
    }
];

 const router = new VueRouter({
     mode: 'history',
     routes: routes
 });

export default router;

Define Vue in App.js

This final step brings you to the point where you must include the required packages in the app.js file. Without further ado, please add the following code in the resources/js/app.js file:

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');
import Vue from 'vue';

import axios from 'axios';
import VueAxios from 'vue-axios';

Vue.use(require('vue-moment'));

import Pagination from './components/pagination.vue'
Vue.component('pagination', Pagination);

Vue.use(VueAxios, axios);

import App from './app.vue';
import router from './routes';

const app = new Vue({
    el: '#app',
    router,
    render: h => h(App)
});

Run your Application

To start the server side pagination app, you need to run the two following commands respectively in two different terminals simultaneously:

npm run watch
php artisan serve

Open the URL in the browser:

http://127.0.0.1:8000/users

Let’s see:

Laravel paginator send the response something like this:

current_page: 1, data: [{id: 51, name: "Vince Beer", email: "johathan25@example.net",…},…],…}
current_page: 1
data: [{id: 51, name: "Vince Beer", email: "johathan25@example.net",…},…]
0: {id: 51, name: "Vince Beer", email: "johathan25@example.net",…}
1: {id: 50, name: "Quentin Schimmel", email: "missouri62@example.net",…}
2: {id: 49, name: "Mr. Lorenza Gerhold III", email: "katheryn.roob@example.com",…}
3: {id: 48, name: "Jefferey Witting", email: "brady71@example.org",…}
4: {id: 47, name: "Linda Berge", email: "pfannerstill.eleonore@example.net",…}
first_page_url: "http://127.0.0.1:8000/api/users?page=1"
from: 1
last_page: 11
last_page_url: "http://127.0.0.1:8000/api/users?page=11"
links: [{url: null, label: "&laquo; Previous", active: false},…]
next_page_url: "http://127.0.0.1:8000/api/users?page=2"
path: "http://127.0.0.1:8000/api/users"
per_page: 5
prev_page_url: null
to: 5
total: 51

I hope you enjoy with vuejs pagination example with laravel tutorial.

Leave a Comment