简体   繁体   中英

Mapbox-gl in a Vue.js single file component (Quasar-Framework)

I would like to implement a Mapbox-gl-js Map within a Quasar Framework (Vue) single file component, but I do not get it working. I found some code on Googlemaps with Vue, and some stuff on Mapbox with React, and try to pull it together from that. With below map initialisation parameters I can get the map showing fine in the index.html (with the mapzen tiles), but want it in the component.

I try to follow this [ https://laracasts.com/discuss/channels/vue/google-maps-and-vue-js](link url) and then adjust it for Mapbox: proj/src/components/maplayout.vue :

<template>
    <quasar-layout>
      <h3>Map</h3>
      <div id='map'></div>
    </quasar-layout>
  </template>

  <script>
  import mapboxgl from '../app'

  export default {
    data () {
      return {}
    },
    create () {
      this.createMap()
    },
    methods: {
      createMap: function () {
        mapboxgl.accessToken = '{{yourmapboxaccestokenkey}}'
        var simple = {
          'version': 8,
          'sources': {
            'osm': {
              'type': 'vector',
              'tiles': ['https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-{{yourmapzenapikey}}']
            }
          },
          'layers': [{
            'id': 'background',
            'type': 'background',
            'paint': {
              'background-color': '#adddd2'
            }
          }, {
            'id': 'majorroad',
            'source': 'osm',
            'source-layer': 'roads',
            'type': 'line'
          }, {
            'id': 'buildings',
            'type': 'fill',
            'source': 'osm',
            'source-layer': 'buildings'
          }]
        }

        // initialize the map
        this.map = new mapboxgl.Map({
          container: 'map',
          style: simple,
          center: [-1.83, -78.183],
          zoom: 5.5
        })
      }
    }
  }
  </script>

  <style>
  </style>

By the way, for mapbox with webpack you need certain loaders, see: [ https://mikewilliamson.wordpress.com/2016/02/24/using-mapbox-gl-and-webpack-together/](link url) But as I got Mapbox working with Webpack before (without vue), I think I have that ok. Actually I do not get any errors in the browser console (but obviously no map appears).

In the app.js file I do not know how to deal with the suggested (maybe not necessary as googlemaps needs a callback, dunno about mapbox/mapzen?!):

var App = window.App = new Vue ({
//code
})

As in Quasar initialization is done like this:

Quasar.start(() => {
  Router.start(Vue.extend({}), '#quasar-app')
})

Which I do not really get...

Any suggestions how to get this working are welcome!

I was close. This actually works:

<template>
  <quasar-layout>
  <h3>Map</h3>
  <div id='map'></div>
  </quasar-layout>
</template>

<script>
import mapboxgl from 'mapbox-gl'
console.dir(mapboxgl)

export default {
  data () {
    return {}
  },
  ready () {
    this.createMap()
  },
  methods: {
    createMap: function () {
      mapboxgl.accessToken = '{{yourmapboxaccestokenkey}}'
      var simple = {
        'version': 8,
        'sources': {
          'osm': {
            'type': 'vector',
            'tiles': ['https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-{{yourmapzenapikey}}']
          }
        },
        'layers': [{
          'id': 'background',
          'type': 'background',
          'paint': {
            'background-color': '#bbccd2'
          }
        },
          {
            'id': 'majorroad',
            'source': 'osm',
            'source-layer': 'roads',
            'type': 'line'
          },
          {
            'id': 'buildings',
            'type': 'fill',
            'source': 'osm',
            'source-layer': 'buildings'
          }]
      }

      // init the map
      this.map = new mapboxgl.Map({
        container: 'map',
        style: simple,
        minzoom: 1.3,
        center: [-74.0073, 40.7124], // Manhattan
        zoom: 16
      })

      this.map.addControl(new mapboxgl.Navigation())
    }
  }
}
</script>

<style>
</style>

I did not change my Vue initialisation.

<template>
  <div class="hello">
    <div id='map'></div>
  </div>
</template>

<script>
import mapboxgl from 'mapbox-gl';

require('../node_modules/mapbox-gl/dist/mapbox-gl.css');

export default {
  name: 'HelloWorld',
  data() {
    return {
      apiKey: {{ your api key }},
    };
  },
  mounted() {
    this.createMap();
  },
  methods: {
    createMap() {
      mapboxgl.accessToken = this.apiKey;
      // init the map
      this.map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v9',
        minzoom: 1.3,
        center: [-74.0073, 40.7124], // Manhattan
        zoom: 16,
      });

      this.map.addControl(new mapboxgl.Navigation());
    },
  },
};
</script>

This might help, I guess!

First thing I noticed: You are initializing the map before DOM is injected into the document. Instead of 'created()' method use 'ready()'.

Quasar is Based on Vue2 version. So ready method is deprecated so instead of that use mounted method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM