Here are the steps to implement pagination in Vue.js with Laravel.
Step 1: Install Laravel.
To use Laravel Valet, you can install Laravel using the following command.
composer create-project laravel/laravel paginate --prefer-dist
Go to your project folder and start the development server with the following command.
php artisan serve
If you are using Laravel Valet, go to your project folder and hit the following command.
laravel new paginate
You can access the project using the following URL: http://paginate.test/
If you are new to Laravel Valet, check out the official documentation. It is effortless to get up and run.
Step 2: Install NPM dependencies and set up db.
Go to your project folder.
cd paginate
Install the NPM dependencies using the following command.
npm install
Vue.js is pre-configured in Laravel. So, you need to compile the CSS and JS files using the following command.
npm run dev
Configure the database inside the .env file.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=paginate DB_USERNAME=root DB_PASSWORD=root
Laravel comes up with two migration files by default. So let us use that and create the table in the database using the following command.
php artisan migrate
It will create a user and password_resets table.
Step 3: Generate Fake user’s data.
To paginate the data, we need some amount of data. For this example, I am using the Faker library to generate the fake users’ data. Then, we use the model factory to create and persist the data in the database. The factory file is inside the database >> factories >> UserFactory.php.
<?php // UserFactory.php use Faker\Generator as Faker; /* |-------------------------------------------------------------------------- | Model Factories |-------------------------------------------------------------------------- | | This directory should contain each of the model factory definitions for | your application. Factories provide a convenient way to generate new | model instances for testing / seeding your application's database. | */ $factory->define(App\User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => str_random(10), ]; });
We generate 100 rows of data. So go to your terminal and enter the following command.
php artisan tinker
You can use it to interact with our Laravel application. Now, generate the data.
factory(App\User::class, 100)->create();
It generates random data up to 100 rows.
Step 4: Create routes and controllers.
First, create an authentication scaffold. So type the following command.
php artisan make:auth
If you do not use auth scaffold, you can create your view; it does not matter here.
This scaffold also gives us some fundamental bootstrap views to work with.
In our tutorial, we will be going to make two UserControllers.
- UserController(It handles the Laravel view)
- UserController(Inside the API folder, responsible for the API response)
Create the first UserController using the following command.
php artisan make:controller UserController
In this controller file, write the following code.
// UserController.php <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; use App\Http\Resources\UserResource; class UserController extends Controller { public function index() { return view('users.index'); } }
We have not created the index view, so inside the resources >> views folder, create a directory called users and inside that, create one file called index.blade.php file.
@extends('layouts.app') @section('content') <div class="container"> Users View </div> @endsection
Define the route for this inside routes >> web.php file.
<?php // web.php Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::get('/users', 'UserController@index')->name('users.index');
Create the second UserController.php file inside the app >> Http >> Controllers >> API folder.
php artisan make:controller API\\UserController
Write the following code inside this UserController.php file.
<?php // API/UserController.php namespace App\Http\Controllers\API; use App\User; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class UserController extends Controller { public function index() { return User::paginate(10); } }
Define routes in the routes >> api.php file.
<?php // api.php use Illuminate\Http\Request; Route::get('/users', 'API\UserController@index');
Now, I can test in this route: http://paginate.test/api/users
Your URL may be different like this: http://localhost:8000/api/users
In the above image, I have minimized the items so that you can see our object’s whole structure.
So, we have created an API, and now Vue needs to consume it. Laravel’s paginate function gives us the metadata we can use to design our Vue Paginate Component.
Step 5: Display the users at the front end.
Inside resources >> assets >> js >> components folder, by default, there is one Vue component called ExampleComponent.vue file. You need to remove this, and inside the components folder, create one more folder called users.
Inside the users folder, create one file called Index.vue.
// Index.vue <template> <div class="row justify-content-center"> <div class="col-md-10"> <div class="card"> <div class="card-header">Users</div> <div class="card-body"> User Data </div> </div> </div> </div> </template> <script> export default { } </script>
We must update the app.js file inside the resources >> assets >> js folder.
// app.js require('./bootstrap'); window.Vue = require('vue'); Vue.component('users-list', require('./components/users/Index.vue')); const app = new Vue({ el: '#app' });
We have created our users-list component.
We need to display this component at this URL: http://paginate.test/users.
So, what we need to do is, inside the index.blade.php file under resources >> views >> users folder, we need to add this users-list component.
@extends('layouts.app') @section('content') <div class="container"> <users-list></users-list> </div> @endsection
The only remaining thing is to fetch and display the data.
Write the following code inside the Index.vue file.
// Index.vue <template> <div class="row justify-content-center"> <div class="col-md-10"> <div class="card"> <div class="card-header">Users</div> <div class="card-body"> <user v-for="user in users" :user="user" :key="user.id"> </user> </div> </div> </div> </div> </template> <script> import User from './partials/User'; export default { components: { User }, data() { return { users: [] } }, mounted() { this.fetchUsers(); }, methods: { fetchUsers() { axios.get('/api/users/').then((res) => { this.users = res.data.data; }); } } } </script>
Create a folder inside the users folder called partials, and inside that folder, create one Vue component called User.vue.
// User.vue <template> <div class="media"> <div class="media-body"> <h4 class="media-heading"> {{ user.name }} </h4> </div> </div> </template> <script> export default { props: ['user'] } </script>
When the component is mounted, we use the client-side HTTP library to send a network request to the Laravel server, get the data, and assign it to the user’s array.
We are getting paginated data, so at this time, we are just getting the first ten rows of the data.
How can we fetch the other data in the structure of pagination? Laravel provides a URL structure in which you can pass the query string of the page, and you can get the other data. The structure is like the following.
http://paginate.test/api/users?page=2
Here, you can change the page value, and we can fetch it according to that data. So we need to perform the same logic in the Vue.
Step 6: Create a Pagination Vue component.
Inside resources >> assets >> js >> components >> users folder, create a new folder called pagination. Inside that folder, create one file called Pagination.vue file.
I am writing the whole logic behind the Vue Pagination inside that component.
// Pagination.vue <template> <nav> <ul class="pagination pagination-lg"> <li class="page-item" :class="{ 'disabled': meta_data.prev_page_url === null }"> <a href="#" class="page-link" @click="next(meta_data.current_page-1)"> « </a> </li> <li class="page-item" v-for="page in meta_data.last_page" :key="page" :class="{ 'active':meta_data.current_page === page }"> <a href="#" @click.prevent="next(page)" class="page-link"> {{ page }} </a> </li> <li class="page-item" :class="{ 'disabled': meta_data.current_page === meta_data.last_page }"> <a href="#" class="page-link" @click="next(meta_data.current_page+1)"> » </a> </li> </ul> </nav> </template> <script> export default { props: ['meta_data'], methods: { next(page) { this.$emit('next', page); } } } </script>
Our final Index.vue component looks like this.
// Index.vue <template> <div class="row justify-content-center"> <div class="col-md-10"> <div class="card"> <div class="card-header">Users</div> <div class="card-body"> <user v-for="user in users" :user="user" :key="user.id"> </user> <pagination :meta_data="meta_data" v-on:next="fetchUsers"> </pagination> </div> </div> </div> </div> </template> <script> import User from './partials/User'; import Pagination from './pagination/Pagination'; export default { components: { User, Pagination }, data() { return { users: [], meta_data: { last_page: null, current_page: 1, prev_page_url: null } } }, mounted() { this.fetchUsers(); }, methods: { fetchUsers(page = 1) { axios.get('/api/users/', { params: { page } }).then((res) => { this.users = res.data.data; this.meta_data.last_page = res.data.last_page; this.meta_data.current_page = res.data.current_page; this.meta_data.prev_page_url = res.data.prev_page_url; }); } } } </script>
We get that page from the emitter and call the API, and Laravel returns a JSON object containing that data. Then, we attach that data to our user’s array and meta_data object. We then pass that data to the User component as well as the Pagination component. Paginate component receives the only meta_data to process the Pagination component.
Now, save the file, and if you are running the npm run watch command, your JS and CSS have already been compiled. So switch to the browser and type this URL: http://paginate.test/users.
You can switch to different pages, and it works fine. Thus, it is helpful for very basic pagination without any page refresh.
That’s it for this tutorial.
Krunal Lathiya is a seasoned Computer Science expert with over eight years in the tech industry. He boasts deep knowledge in Data Science and Machine Learning. Versed in Python, JavaScript, PHP, R, and Golang. Skilled in frameworks like Angular and React and platforms such as Node.js. His expertise spans both front-end and back-end development. His proficiency in the Python language stands as a testament to his versatility and commitment to the craft.
Thank you.
Is it possible to integrate content management for final user?
For example create posts, edit/delete posts.
Also im interested to know if there is any online service which could work as CMS for vue application
I’m just started learning vue
hi, Bogdan?
see https://www.storyblok.com/
HI, Krunal
axios must be installed? if so, how to do it in Laravel?
so maybe you will demonstrate how to install npm packages, for use in * .vue. In the Laravel project.
Nice Tutorial.!