0

I’m tinkering with my first laravel-vue application and ran into a problem, first some context.

In order to share my global app data from laravel to view I use an inline script like this: I use laravel’s AppServiceProvider to share global data with my view, afaik on each request this data will be refetched:

public function boot()
    {
        View::composer('*', function ($view) {

            $globals = [
                'appName' => Globals::where('name', 'Nombre de la aplicación')->pluck('value')->first(),
                'appDescription' => Globals::where('name', 'Descripcion de la aplicación')->pluck('value')->first(),
                'appBio' => Globals::where('name', 'Biografia de la aplicacion')->pluck('value')->first(),
                'appBookingPhone' => Globals::where('name', 'Télefono de contacto')->pluck('value')->first(),
                'appPrefixBookingPhone' => Globals::where('name', 'Teléfono para mostrar')->pluck('value')->first(),
                'appMail' => Globals::where('name', 'Email de contacto')->pluck('value')->first(),
                'appFullAddress' => Globals::where('name', 'Dirección completa')->pluck('value')->first(),
                'appZipAddress' => Globals::where('name', 'Contador de visitas')->pluck('int_value')->first(),
                'appSchedules' => $schedules = Schedule::all(),
                'appTwitter' => config('globals.twitter'),
                'appFacebook' => config('globals.facebook'),
                'appInstagram' => config('globals.instagram'),
                'appShowNewsletterModal' => Modal::checkIfShowModal(),
                'appAllClassesPosts' => Post::withCategory('Clases')->take(10)->get(),
                'appAllBehaviourPosts' => Post::withCategory('Conducta canina')->take(10)->get(),
                'appAllTrainingPosts' => Post::withCategory('Formación')->take(10)->get(),
                'appLoggedUser' => Auth::user(),
                'appSchedules' => $schedules = Schedule::all()
            ];
            //dd($globals['appAllBehaviourPosts']);
            $view->with('globals', $globals);
        });
    }

Then I use an inline script in my blade template to share the data with vue’s instance:

<script>
window.APP = @json( ["pageInfo" => $pageInfo, "globals" => $globals] );
</script>

Then inside my MainHeader component I try to access APP variable but I get the following error:

[Vue warn]: Property or method "APP" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <MainHeader> at resources/assets/js/components/headers/MainHeader.vue
       <Root>

This is my MainHeader component:

<template>
<header class="header_maincontainer">
    <div class="header_small_container">
        <div class="header_small_contact_container" style="">
            <span class="header_small_text1">Llamanos al: </span>
            <i class="header_small_phone_icon fa fa-phone"></i>
            <a class="header_small_phone_number" :href="'tel:${APP.globals.appPrefixedBookingPhone}'">{{ APP.globals.appBookingPhone }}</a>
        </div>
        <div class="header_small_social_container" style="">
            <a v-if="APP.globals.twitter != ''" :href="'${APP.globals.twitter}'" target="_blank" class="header_small_social_icon"><i class="fa fa-twitter header_fa"></i></a>
            <a v-if="APP.globals.facebook != ''" :href="'${APP.globals.facebook}'" target="_blank" class="header_small_social_icon"><i class="fa fa-facebook header_fa"></i></a>
            <a v-if="APP.globals.instagram != ''" :href="'${APP.globals.instagram}'" target="_blank" class="header_small_social_icon"><i class="fa fa-instagram header_fa"></i></a>
        </div>
        <a class="header_small_auth_container" href="/login" v-if="APP.globals.user == ''">
            <div class="header_small_login_icon"><i class="fa fa-user header_fa"></i></div>
            <span class="header_small_login_text" title="Iniciar sesión">Iniciar</span>
        </a>
        <div class="header_small_auth_container" v-if="APP.globals.user != ''">
            <a href="/panel-administrador" class="header_small_mail_icon"><i class="fa fa-cog header_fa"></i></a>
            <a href="" class="header_small_login_icon"><i class="fa fa-sign-out header_fa"></i></a>
            <a href="/logout" class="header_small_login_text" title="Cerrar sesión">Salir</a>
        </div>
    </div>
    <div class="header_big_container">
        <div class="header_big_logo_container">
            <a class="header_big_logo_link_wrapper" href="/" title="'Página de inicio de ${APP.globals.appBookingPhone}'" style="background-image:url('/img/logo_yellow.png');"></a>
        </div>
        <div class="header_big_texts_container">
            <span class="header_big_texts_3">Adiestramiento Canino a Domicilio en Málaga, Costa de Málaga e Interiores</span>
            <span class="header_big_texts_2">Tus especialistas en comportamiento canino</span>
            <a class="header_big_texts_phone" :href="'tel:${APP.globals.appPrefixedBookingPhone}'">{{ APP.globals.appBookingPhone }}</a>
        </div>
    </div>
</header>
</template>

I'm stuck here!

tony19
  • 125,647
  • 18
  • 229
  • 307
  • If you want to use `APP` in your Vue templates, you're going to have to add it to data somehow. The simplest method would be something [like this](https://codesandbox.io/s/7jm3jnz331) (note that the APP object is created in index.html and APP is added to the data of the `App` component). I'm not sure I would recommend it though, because your component would be relying on something global. Generally you would want to pass it in to your component via props. – Bert Oct 25 '18 at 12:26
  • [I like this version a little better](https://codesandbox.io/s/64z2xp0xpn); `APP` is imported into the Vue and passed to the component. – Bert Oct 25 '18 at 12:29
  • Honestly there are many ways to do it. [Some of this is covered here as well](https://stackoverflow.com/questions/43193409/global-data-with-vuejs-2/43193455#43193455). – Bert Oct 25 '18 at 12:31

1 Answers1

0

First of all if you want to share laravel data with vue.js I prefer to use PHP library for that and composer view of course. https://learninglaravel.net/transform-php-vars-to-javascript


To share that sort of data you have here you can choose between two directions:

  • Get your data from API (build routes with GET for specyfic data) and in VUE use AXIOS to get data from backend
  • Share with composerViews

Your approach is similar to composer views but not ideal :) Read here: https://laravel.com/docs/5.7/views#view-composers more about that.

IF you choose composerViews be sure that you are serving data to a view that are only needed by this route. Don't send everything if you are not using it.

For my, private, best option will be if you share with composerViews only required data as user info, and rest of it get with AXIOS from backend at every component with nice loader on that.


Still, if you want to find solution for your structe please look that you are matching this data to window.APP but in component you are using APP.{name}. APP is not defined for local purposes and you need to use window.APP.{name}