1

我在使用 Vue.js 和 Bulma 选项卡组件(通过 Buefy)加载传单地图时遇到问题。

如果地图放置在选项卡内,则在调整浏览器窗口大小之前它不会加载所有图块。

如果地图放置在 Bulma 选项卡组件之外,则它会毫无问题地加载。

调用map.invalidateSize()似乎有帮助,但是要在选项卡更改时自动执行此操作,我必须使用它来调用它setTimeout并放置非常大的延迟,例如 1 秒 - 这非常难看。

如果没有这种invalidateSize解决方法,如何使它工作?

问题示例:https ://codepen.io/alxxnder/pen/zyYxwd

没有问题的示例:https ://codepen.io/alxxnder/pen/LMYEjr

代码:

new Vue({
  el: '#app',
  data: {
    map: null,
  },
  methods: {
    invalidateSize: function() {
      this.map.invalidateSize();
    }
  },
  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);
  }
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Leaflet Test</title>

  <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">
</head>

<body>


  <div class="section">
    <div class="container" id="app">
      <b-tabs 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>
        </b-tab-item>
      </b-tabs>
    </div>
  </div>


</body>

<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>

</html>

4

1 回答 1

0

正如Data-toggle tab does not download Leaflet map中所解释的,这个问题是由于你的地图容器在你初始化它时还没有它的完整大小引起的。如果您的地图在最初隐藏的选项卡中(例如在选项卡 2 中),您可能更容易理解它。

至于您最初处于活动状态的选项卡(即选项卡 1),Buefy / Bulma 可能仍需要一些时间才能显示选项卡内容。

由于选项卡转换完成时没有事件,因此您必须等待转换持续时间才能调用该invalidateSize方法。在您的情况下,300ms 似乎没问题。

然后,当用户更改选项卡时,您还应该再次调用它(请参阅 Buefy 选项卡事件),否则如果在隐藏选项卡时浏览器更改了大小,同样的问题会再次发生。

在 2 个选项卡中使用地图进行演示:

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>

于 2018-12-09T01:25:50.340 回答