Laravel PHP Vue VueJS

How to pass data from Laravel to VueJS

August 19, 2019 by Matt Glover

When you’re starting out with Laravel and VueJS you will soon come to the point of wanting to pass data from a Laravel controller to a Vue component. This article outlines how to get your data from a controller through to rendering it within a Vue component on a page.

 

Setting up our demo data

Firstly, we’ll start with the data for our little demo. We’ll assume there is a Product model which has a product title, description and price, and an associated Category model with a name.

In my case, so that I had some data to work with, I created two Factories to generate 5 categories and 20 products using both the default Faker and a custom Faker class (to generate product titles and category names).

Using “php artisan tinker” the record creation looks something like this:

factory(App\Category::class,5)->create();
factory(App\Product::class,20)->create();

At this stage, we have two models – Product and Category. The database has been populated with some sample data so we can now turn to retrieving it from the database and passing it to our Vue component.

 

Retrieving the data from the database

Let’s say you have a controller that returns a list of products that you want to render as an unordered list on a page along with a set of product categories. Your controller might look something like this:

<?php

namespace App\Http\Controllers;

use App\Category;
use App\Product;
use Illuminate\Http\Request;

class WelcomeController extends Controller
{

    public function index()
    {

        $categories = Category::all();
        $products = Product::all();

        return view('welcome', ['categories' => $categories, 'products' => $products]);

    }

}

 

For the sake of simplicity, we are just going to return all records for each model and pass them to a Laravel view called “welcome”. Laravel will look for a blade file called welcome.blade.php in /resources/views and pass $categories and $products to it. Both $categories and $products will be available to us in the Blade file as PHP variables.

I’ve used the Laravel scaffolding to generate a layout file (php artisan make:auth) so my welcome.blade.php file looks like this:

@extends('layouts.app')

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

                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

 

Our VueJS component

It’s time to turn to the creation of our VueJS component which will need to receive the data from the Laravel controller, and display the data as HTML.

In the /resources/js/components directory, we’ll create a VueJS component called ShopComponent.vue. We’ll expect to be given two data properties and create a template to display them. Here is what our simple component might look like:

<template>
    <div>

        <h2>Categories</h2>
        <ul>
            <li v-for="category in categories">{{category.name}}</li>
        </ul>

        <h2>Products</h2>
        <ul>
            <li v-for="product in products">{{product.title}} ${{product.price}}</li>
        </ul>

    </div>
</template>

<script>
    export default {
        props: ['categories', 'products'],
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

 

The “props:” directive indicates what properties must be passed in for this component to be used. In our case that will be “categories” and “products”. For simplicity, we will use VueJS to output the data from both properties as two unordered lists. Don’t forget to register the component in app.js and rebuild (npm run dev or npm run production).

Note that “{{ }}” notation is used to output the properties with dot notation used to access member properties. So for example, {{ category.name }} will output the name associated with the current category, and {{ category }} would output the whole object in a JSON encoded format. This can be useful for debugging to example all the member property values.

 

Bringing it all together

Now that we have our data, our controller to retrieve it, our component to display it we can bring it all together. The way to pass the PHP variable data to the Vue component is to use json_encode within our blade. The format is as follows:
“{{ json_encode($categories) }}”

To invoke our component within our welcome.blade.php, we would structure it like this:

<shop-component :categories="{{ json_encode($categories) }}" :products="{{ json_encode($products) }}"></shop-component>

This instructs the blade engine to load the shop-component Vue component and pass in two properties, :categories and :products. Each of these is associated with the Laravel Controller generated PHP variable in json encoded format. This data will then be made available in the Vue component in the relative prop values.

Our final blade looks like this:

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Shop</div>
                    <div class="card-body">
                        <shop-component :categories="{{ json_encode($categories) }}" :products="{{ json_encode($products) }}"></shop-component>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

 

And here’s the result!

If you have any feedback or questions please contact me at matt@sparkeleven.com.au

enjoy this article? don't forget to share.
WHATS NEXT?

Call us now to book an obligation free strategy session