How to use Laravel Blade and Vue.js together

Laravel

How to use Laravel Blade and Vue.js together

Laravel provides Vue.js support out of the box which means that we do not have to create a separate Vue project. Instead, we can write our Vue logic directly in the Laravel resources folder.

In this article, we will look at how we can write and use Vue components inside our blade files.

Follow this guide if you don’t have the Laravel application installed.

Let’s say that that somewhere in our application we want to have a table of all users. We want to have a Laravel blade file that inside, calls a Vue component that will perform the process of fetching and displaying users. Sounds good, alright then, let’s get started.

If you don’t already have a users table, you can create one now. To be honest, it can be anything you want, but for the sake of this article, we will stick to the users table, logic will be the same for any.

php artisan make:migration create_users_table.
If you generated Laravel’s default authentication you don’t need to do this.

Next, we will create a seeder with a factory for our users table. We need some dummy data to play with.

php artisan make:seeder UserTableSeeder

In the default Laravel application UserFactory model is already created. The thing we need to do is to use the factory inside our UserTableSeeder and call the seeder from DatabaseSeeder class.

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $users = factory(User::class, 100)->create();
    }
}
class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
         $this->call(UsersTableSeeder::class);
    }
}


After this is done, go ahead and run:
php artisan migrate:fresh –seed.
This command will drop and migrate all tables and run all seeders.

Now let's create a new web route, a user controller, and a view blade file where we will place our user table Vue component.

Route::get('/users', 'UserController@index')->name('user.index');


php artisan make:controller UserController

class UserController extends Controller
{
    public function index (Request $request)
    {
        return view('pages.user.index');
    }
}


I created the following view structure but you are free to place it anywhere you want.

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-12">
                <div class="card">
                    <div class="card-header">Users</div>

                    <div class="card-body">
                        Users table will soon be here
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection


If you visit http://127.0.0.1:8000/users you should see the following screen


Now we can start working on our user index Vue component. I usually create a folder for each component.

<template>
        <table class="table table-hover">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Email</th>
                    <th scope="col">Updated At</th>
                    <th scope="col">Created At</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="user in users" :key="user.id">

                </tr>
            </tbody>
        </table>
</template>
<script>
    export default {
        data() {
            return {
                users: []
            }
        },
        created() {
            // TODO ajax request to fetch users
        }
    }
</script>


It is important to tell Vue that our user component exists and that it is available under the user-index name.

Vue.component('user-index', require('./components/User/UserIndex.vue').default);


Now we can replace our silly text with our Vue component.

<div class="card-body">
    <user-index></user-index>
</div>


After we refresh the page, we can see that it is starting to look like something.


Now we need an ajax request inside our created() method that will fetch the users and populate our users array(). For this, we will use Axios.

In our UserController let’s add another method that will paginate and return all users.

public function indexJson()
{
    $users = User::paginate(20);
    return UserResource::collection($users);
}


We can create a UserResource by running a simple command.

php artisan make:resource UserResource.

These resource files will be created in Http\Resources folder. We will modify toArray() method and format timestamp fields.

public function toArray($request)
{
    return [
        'id'    => $this->id,
        'name'  => $this->name,
        'email' =>$this->email,
        'updated_at' => Carbon::parse($this->updated_at)->diffForHumans(),
        'created_at' => Carbon::parse($this->updated_at)->format('m/d/Y'),
    ];
}


diffForHumans()
Carbon method will give us a slick and very popular time format such as one hour ago, in two weeks, and etc.

We also need to create a route that will Axios call in order to execute the command. This will be an API route placed in API file In your routes folder.

Route::get('/users', 'UserController@indexJson');


Now we can create our Axios get request and finish our UserIndex component.

<template>
        <table class="table table-hover">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Email</th>
                    <th scope="col">Updated At</th>
                    <th scope="col">Created At</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(user, index) in users" :key="user.id">
                    <td>{{ index + 1 }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.email }}</td>
                    <td>{{ user.updated_at }}</td>
                    <td>{{ user.created_at }}</td>
                </tr>
            </tbody>
        </table>
</template>
<script>
    export default {
        data() {
            return {
                users: []
            }
        },
        created() {
            axios.get('/api/users')
                .then(response => {
                    this.users = response.data.data;
                })
                .catch(error => {
                    console.log("Error", error)
                })
        }
    }
</script>


This is pretty much how you can use Vue components inside blade files in the case where you do not have a single page application.

Having Vue for handling forms, and tables, gives a website a modern look and leaves a good impression on the user.

It is worth mentioning that you can also directly pass php variables as props to Vue components. Let's pass a currently logged user name to our index blade and display some welcoming message.

Our UserController

public function index (Request $request)
{
    $authUser = Auth::user();
    return view('pages.user.index', compact('authUser'));
}


Our user index blade file

<div class="card-body">
    <user-index :auth-user="{{ $authUser }}"></user-index>
</div>


Our UserIndex Vue component

<template>
        <div>
            <h1>Hello, {{ authUser.name }}.</h1>
            <table class="table table-hover">
                <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Name</th>
                    <th scope="col">Email</th>
                    <th scope="col">Updated At</th>
                    <th scope="col">Created At</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(user, index) in users" :key="user.id">
                    <td>{{ index + 1 }}</td>
                    <td>{{ user.name }}</td>
                    <td>{{ user.email }}</td>
                    <td>{{ user.updated_at }}</td>
                    <td>{{ user.created_at }}</td>
                </tr>
                </tbody>
            </table>
        </div>
</template>
<script>
    export default {
        props: {
            authUser: {
                type: Object
            }
        },
        data() {
            return {
                users: []
            }
        },
        created() {
            axios.get('/api/users')
                .then(response => {
                    this.users = response.data.data;
                })
                .catch(error => {
                    console.log("Error", error)
                })
        }
    }
</script>


This wraps this article. Good luck on making awesome stuff. You have a coders blessing.

Show comments

Laravel

5 min

How to make Laravel authentication

Laravel provides a neat function that quickly generates a scaffold of routes, views, and controllers used for authentication.

Laravel

7 min

How to install Laravel application

This article will cover how to install and create a local development environment for your Laravel application. There are only a couple of steps that needs to be done.

Laravel

3 min

How to set appropriate Laravel permissions on Linux server

After publishing your Laravel application to a real web server, you discover then some of your functionalities are failing.

Codinary