vue-leaflet/Vue2Leaflet

Using imported scripts, geojson and tile layers don't show together

mdougherty3 opened this issue · 5 comments

Description

When using CDN script imports instead of using npm, I cannot get a geojson and a tile layer to show together. It seems like whichever comes first under the tag is rendered and not whatever comes next.

Live Demo

I setup an example here: https://jsfiddle.net/7am9hk3s/16/
If you comment out the component or move it after the component, you will see the geojson layer get rendered but not the tile layer anymore.

Steps to Reproduce

Expected Results

Geojson layer should be rendered overtop of the tile layer while being able to see both.

Actual Results

Only the first listed layer is rendered.

Browsers Affected

Tested on:

  • Chrome
  • Firefox
  • Edge

Versions

  • Leaflet: v1.7.1
  • Vue: v2.6.12
  • Vue2Leaflet: v2.6.0

async created() {
const response = await fetch('https://rawgit.com/gregoiredavid/france-geojson/master/regions/pays-de-la-loire/communes-pays-de-la-loire.geojson');
this.statesData= await response.json();
},

mikeu commented

@mdougherty3 thanks for this report! To be honest I've never really tried to write a Vue app without a package manager and build system, so I'm afraid I don't have much insight into why exactly it's happening, but I did a bit of playing around and found two things that might help.

First, it actually is only including whatever the first sub-component in the map is. I tried adding a layers control, and it either appears empty of layers if it's first, or doesn't appear at all if it comes later. And the later layers aren't being hidden, they actually aren't there—if you have the network tab open while the geojson layer is first, you can see that zero requests are made to the OSM tile server.

Second, I did find a work-around! If you simply cut the map source out of the HTML and paste it as-is into the template property of the Vue app component, then your example starts working as expected: https://jsfiddle.net/munderwood/620z8csh/1/

After a quick search it seems as if most pages discussing using Vue via CDN use the approach of having a template string, instead of writing the app div in the HTML as if it were a single-file component, though I haven't found any discussion as to why they do it that way. Regardless, is that an approach that could work for you?

mikeu commented

And @Ramaniks , thank you for the thought there. That would indeed be a good approach if the problem were that the geojson data hadn't loaded yet. But in this case, by loading it into the global namespace in a script tag, the data does in fact already exist in the statesData variable before the component is created, so that's not the problem here.

@mikeu This is really interesting that adding the template in this way works fine. I usually use Vue in a package manager system but occasionally just throw it in an import tag for certain legacy apps and pages and I've just always used the SFC style that I'm used to with Vue.

This should be able to work fine for me doing it this way, thanks for figuring out this workaround!

Using default tags instead of self-closing ones solves the issue too, probably related to "use it in a template string"

I mean

<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-geo-json v-if="show" :geojson="geojson" :options="options" :options-style="styleFunction"></l-geo-json>
<l-marker :lat-lng="marker"></l-marker>     

instead of

<l-tile-layer :url="url" :attribution="attribution" /></l-tile-layer>
<l-geo-json v-if="show" :geojson="geojson" :options="options" :options-style="styleFunction" />
<l-marker :lat-lng="marker" />