I created a vue component based on MapBox, which is restricted in initializations before it costs money and that is perfectly fine. But I want to reduce reinitializations of my map component for their and my sake. That's why I thought if it is possible to define the component once, pass in some properties and then handle the state via vuex.
Right now, I'd have to import my component and add the data like this:
<Map
:sources="geoData.sources"
:layers="geoData.layers"
:mapOptions="mapOptions"
:componentOptions="{ drawingEnabled: toggleMapDrawing, activeLayers: activeMapLayers, activeMarkerGroups: [] }"
@loaded="onMapLoaded" @selectedMarkers="onSelectedObjects"/>
The componentOptions are being watched, so the component changes its state accordingly.
My ideas/approaches so far were the following:
- I thought about adding the snippet above to the root vue file, but that won't help since I want to place the map component dynamically and not statically before the rest of the page content.
- Passing a rendered vue component into a variable and appending that later would be a bit too hacky, if it is even possible.
- Using slots, but from what I've seen in the docs, it's not possible to use a slotted component from a parent component in a child like this.
- The best idea that has come to my mind was to define the actual MapBox variable (which I suppose triggers the API for initialization) and then save that globally using the store or something. But since that will immediately append the component to a DOM element that will be specified in the options, so I'd have to store that somehow, too.
The initialization of the map happens in the mounted hook of the component and looks like this:
const baseOptions = {
accessToken: process.env.MAPBOX_TOKEN,
container: 'map',
style: process.env.MAPBOX_STYLE_URL,
minZoom: 10,
maxZoom: 20,
zoom: 13,
bearing: 150,
pitch: 50
}
this.map = new mapboxgl.Map(Object.assign(baseOptions, this.mapOptions))
if (!this.map) { throw new Error('Could not create map. Make sure the token is valid.') }
I might be wrong, maybe there's a better way or maybe this whole idea might be garbage, but hopefully it's not. Also please note that I'm not using the vue-mapbox module, because it's not being maintained anymore.
I'm thankful for any ideas and hints :)
componentOptionsare being watched inside of the component to handle the state...