[Vuejs]-Leaflet map not loading in Bulma tab using Vue.js

0👍

As explained in Data-toggle tab does not download Leaflet map, the issue is caused by the fact that your map container does not have yet its full size when you initialize it. You may understand it more easily if your map had been in an initially hidden tab (e.g. in tab 2).

As for your initially active tab (i.e. tab 1), it is probable that Buefy / Bulma still takes some time to reveal the tab content.

Since there is no event when the tab transition completes, you have to wait for the transition duration before calling the invalidateSize method. In your case, 300ms seems to be fine.

Then you should also call it again when the user changes the tab (see Buefy tabs events), otherwise should the browser had changed size while your tab was hidden, the same issue would happen again.

Demo with maps in the 2 tabs:

new Vue({
  el: '#app',
  data: {
    map: null,
    map2: null,
    tabMaps: []
  },
  methods: {
    invalidateSize: function(tabIndex) {
      setTimeout(() => {
        if (typeof tabIndex === "number") {
          this.tabMaps[tabIndex].invalidateSize();
        } else {
          // invalidate all maps
          this.tabMaps.forEach(map => {
            map.invalidateSize();
          });
        }
      }, 300);
    }
  },
  mounted() {
    this.map = L.map('map').setView([38.63, -90.23], 12);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);

    // map2 in tab2
    this.map2 = L.map(this.$refs.map2).setView([38.63, -90.23], 12);
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(
      this.map2
    );

    this.tabMaps.push(this.map); // 0
    this.tabMaps.push(this.map2); // 1
    this.invalidateSize();
  }
})
<link rel="stylesheet" href="https://unpkg.com/buefy@0.7/dist/buefy.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css">

<div class="section">
  <div class="container" id="app">
    <b-tabs @change="invalidateSize" position="is-centered">
      <b-tab-item label="Tab 1">
        <div class="section">
          Tab 1
          <div class="map" id="map" style="height: 400px; width: 100%"></div>
          <button class="button is-info" @click="invalidateSize()">invalidateSize</button>
        </div>
      </b-tab-item>
      <b-tab-item label="Tab 2">
        <div class="section">
          Tab 2
          <div class="map" ref="map2" style="height: 400px; width: 100%"></div>
        </div>
      </b-tab-item>
    </b-tabs>
  </div>
</div>

<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/buefy@0.7/dist/buefy.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>
👤ghybs

Leave a comment