Home » Php » VueJS components

VueJS components

Posted by: admin October 29, 2017 Leave a comment

Questions:

I want to make use of VueJS components to clean up my scripts. Therefore I have a component for each page I am loading in into Laravel. Everything works fine so far. But I have issues transfering my current script logic to a component.

This is the current script setup importing the to be used components:

main.js

import HomeView from './components/HomeView.vue';
import IncidentView from './components/IncidentView.vue';

window.app = new Vue({
   el: '.content',

   components: {
       HomeView, IncidentView
   },

   methods: {

       // Init GIS
      init: function() {

          // Initialize GIS Map
         initGISMap(this.$els.map);
      },
    }
(...)
}

Key for me is the window.app = new Vue... part. I make use of google maps and therefore when the page is loaded it searches for an app.init method. This is part of the script I am loading withing the blade template:

<!DOCTYPE html>
<html>
<body class="hold-transition skin-blue sidebar-mini">
        <section class="content-header">
            <h1>
                @yield('page_title')
                <small>@yield('page_description')</small>
            </h1>
        </section>

        <!-- Main content -->
        <section class="content">

            @if (isset($vueView))
                <component is="{{ $vueView }}">
            @endif
                @yield('content')
            </component>

        </section>
        <!-- /.content -->
<script src="https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places&callback=app.init" async defer></script>
</body>
</html>

The individual pages (where I create for each a module in Vue) look like this:

@extends('app', ['vueView' => 'home-view'])
@section('page_title', 'title')
@section('page_description', 'title')

@section('content')
content
@endsection

By defining the vueView variable, the correct module I am importing in my script is used.

The goal is to use HomeView component as the main google maps view. And the other components for different pages I load when clicking the corresponding link in my theme. At the end, I do not want to have all VueJS code in one script. Therefore the models.

When I transfer all the content of this current JS file, I get an error complaining that app.init is not a function. The component looks like this:

<script>
export default {
   data: {
       // SEARCH
       addressComponents: '',
       autocompletePlace: '',
       autocompleteAddress: '',
(...)
}

How do I modify my component in a way, that the app.init load would still work?

Answers:

Someone has already mentioned GuillaumeLeclerc/vue-google-maps which is available on npm as vue-google-maps, but be warned that that version only works with vue 1.x

If you are using v2, look at this great vue2 fork xkjyeah/vue-google-maps – it’s available as vue2-google-maps on npm.

The API is straightforward and doesn’t diverge far from the v1 version, and the repository is much more active than its upsteam counterpart.

It really made my vue map work a lot more painless than rolling my own, which is what I was initially doing.

I hope that helps

Questions:
Answers:

Maybe you should use, or at least study the code, of a package that does that.

For example, you can check vue-google-maps on Github : https://github.com/GuillaumeLeclerc/vue-google-maps/

It defines a whole lot of Components related to Google Maps.

Questions:
Answers:

If I understand you right, you have a Google Maps script which, when loaded, calls window.app.init, right?

Does your Vue component have an init() method (none is shown above)? If there was one, it would need to be at app.methods.init() remember for VueJS, standard callable methods live under methods key.

Alternatively: you don’t mention if your app.init is part of the Vue component or not. If its not it would appear that your app.init function is being overridden because you are redefining window.app as your vue component.

Lastly, if your init is part of Vue, is your google maps fn callback calling this init() before the Vue is loaded and therefore no such method exists (yet)?