I’m currently creating a vue3 cli app that uses vue-leaflet (the vue3 compatible version)
Everything works great on my local dev environment but once my app is built the map doesn’t load, even when I resize like this thread explains well.
I tried using the leafletObject.invalidateSize()
method but nothing changed.
My map is a component called using a v-if on first call (switch between a list view and the map) and a v-show once it has been initialized
<transition name="fade" mode="out-in"> <Map v-if="mapInit" v-show="(!mobileView && !listing) || (mobileView && !listing && !getFiltresMobile)" :liste="getFilteredList"/> </transition>
Here is what I get on my dev version when I use npm run serve
Here is the result on the prod version
Here is the relevant part of my code, I can add more if you think more code needs to be shown
<template> <div id="map"> <l-map v-if="!loading" :style="mapHeight" :zoom="zoom" :center="centerValue" :options="{tap : false}" ref="map"> <l-tile-layer :url="url"></l-tile-layer> <l-marker v-for="(marqueur) in mapData" :key="marqueur.id" :visible="isFiltered(marqueur)" :lat-lng="marqueur.latLng" :ref="setMarkerRefs" @click="markerClick(marqueur.latLng)"> <l-icon :icon-url="checkActive(marqueur.latLng)" :icon-size="[30 , 37]" :popup-anchor="popupUpPosition" :icon-anchor="[15, 37]"/> <l-popup :options="popupoptions"> <MarqueurPopup :contenu="marqueur"/> </l-popup> </l-marker> </l-map> <Loader v-if="loading"/> </div> </template>
JS
<script> import "leaflet/dist/leaflet.css" import { LMap , LTileLayer , LPopup , LMarker , LIcon } from "@vue-leaflet/vue-leaflet"; export default { name: "Map", props : ['liste'], components: { Loader, MarqueurPopup, LMap, LTileLayer, LMarker, LPopup, LIcon, }, data() { return { url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', zoom: 13, mapData : [], markerRefs : [], markerRefsDef : [], popupoptions : { maxWidth : 1000, minWidth : 300, closeButton : false, } }; }, beforeMount() { this.initMap() }, mounted() { setTimeout( () => { console.log(this.$refs.map.leafletObject) // returns the leaflet map objects this.$refs.map.leafletObject.invalidateSize(); // no error but does nothing }, 1000); }, computed : { popupUpPosition() { if (window.innerWidth < 768) { return [0, 74] } return [0, -37] }, mapHeight() { let colonneValue = window.innerWidth / 12; if (colonneValue < 115) { colonneValue = 115 } let height = window.innerHeight - colonneValue; return {height : height+'px'} }, }, methods : { async initMap() { this.$store.commit('changeLoading' , true); this.mapData = [] this.mapData = this.getFilteredList this.$store.commit('changeLoading' , false); }, } } </script>
Is there a way to check if the invalidateSize()
methods triggers ? My console.log get no errors but nothing changes so maybe it doesn’t trigger the method ?
Answer
Rather looks like the Leaflet CSS is incorrectly loaded in your production bundle: tiles are scrambled up, no zoom and attribution controls.