laravel

How To Preload Laravel DB Data Into Vue As Global Variable

If you are building an application with Laravel and Vue that’s not a SPA (Single Page Application) and you have more than 50 Laravel routes, you will quickly realize that you need some kind of central storage to keep track of the routes.

You will probably be using Axios to call these routes and communicate to your database so it becomes really difficult to keep two logs of routes, one of the Laravel side and the other inside Vue components.

Having a Vuex store for this is not necessary but what you can do is to have a global variable loaded into your Vue app instance that will be accessible to all of your components, passed as a prop.

Let’s have a look at this.

First you have a few routes in here as an example:

Route::post('/organizations/lpi', 'OrganizationController@getLpiData')->
name('get-organization-lpi-data')->middleware('admin');

Route::post('/organizations/lpi/calculate', 'OrganizationController@calculateLpi')->
name('calculate-organization-lpi')->middleware('admin');

Route::post('/organizations/lpi/historical/get', 'OrganizationController@getHistoricalLpiData')->
name('get-organization-historical-lpi-data');

Route::post('/organizations/lpi/stats/get', 'OrganizationController@getLpiStatsData')->
name('get-org-lpi-stats-data')

Imagine this was a list of 100 routes and you needed to keep track of all of them inside each Vue component.

One way to do this is to preload it with PHP the way it is.

So you can create a Props.php file and in there just have a regular class:

<?php
namespace App\YourDomain;

class Props
{
    public static function get()
    {
      // In case you want to group it, you can
      return [
    'organizations' => [
         'get_organization_lpi_data' => route('get-organization-lpi-data'),
         'calculate_organization_lpi' => route('calculate-organization-lpi')
        ]
     ];
    }
}

Then in your home.blade.php you can generate this file:

<head>
<script>
        var props_settings = "{!! base64_encode(json_encode($props)) !!}";
    </script>
</head>

Above, you can see that the $props variable just showed up in there. That’s not by accident though. I had a MainComposer class set up so it passes this to all the blade templates.

<?php

namespace App\Http\ViewComposers;

class MainComposer
{
    protected $excluded_views = [
        'emails.excluded_blade_template',
    ];        
 
    /**
     * Create a new profile composer.
     *
     * @return void
     */

    public function __construct()
    {}

    /**
     * Bind data to the view.
     *
     * @param  View  $view
     * @return void
     */

    public function compose(View $view)
    {
        $props = Props::get();
        if (!$this->viewExcluded($view->name())) {
            $view->with('props', $props);
        }
    }

    public function viewExcluded($name)
    {
        foreach ($this->excluded_views as $view) {
            if ($name == $view) {
                return true;
            }
        }

        return false;
    }
}

And finally what we need to do is to load this inside your main Vue instance.

new Vue({
    el: '#main-home',
    data: {
        settings: JSON.parse(atob(props_settings)), // Global variable
    },
.
.
.

In case you have a template for a simple component that lives in this Vue Instance then you can just paste the prop to it:

<my-new-component :settings="settings"></my-new-component>

In case you want to optimize this even more, you can make a mixin for example so it automatically includes all the props needed.

And this is how you pass laravel resources data into your Vue realm. You can also preload any real data inside the Props like maybe your basic user data so you always have it on the fly.

Again, we could debate over this since this might be something that you could use with a Vuex store, but it will depend if you will want to use it as a state only or you want to mutate it.

About the author

Avatar

laravelrecipies