首页 文章

在调整屏幕大小之前,无法使用VueJs和传单在DIV上显示所有 Map

提问于
浏览
1

我正在使用VueJS和Leaflet来显示具有特殊本地化的 Map . 我已经在index.html中添加了css传单,如文档中所述 .

link rel =“stylesheet”href =“https://unpkg.com/leaflet@1.2.0/dist/leaflet.css”>

但我只有 Map 的一部分 . 我必须改变屏幕的大小以使所有 Map 都带有标记 .

enter image description here

这是我实现 Map 的地方(iMap.vue)

<template>
  <div id="professionnel">
    <b-row>
     <b-tabs>
        <b-tab title="A" >
            <div>
                <b-col class="col-12">
                    <div>Où nous joindre</div>
                </b-col>
            </div>
        </b-tab>
       <b-tab title="B">
            <div class="tab-content-active" >
                <b-col class="col-6">
                    <div>heure</div>
                </b-col>
                <b-col class="col-6 data_map">
                    <iMap1></iMap>
                </b-col>
            </div>
        </b-tab>
      </tabs>
    </b-row>
  </div>
</template>

<script>
import iMap1 from './iMap1'

export default {
  name: 'professionnel',
  components: {
    iMap1
  },
  data() {
    return {}
  }
</script>

这是Map(iMap.vue)的vue

<template>
        <div id="imap1" class="map" >
        </div>
    </template>

    <script>

    import leaflet from 'leaflet'

    export default {
      name: 'imap1',
      components: {
        leaflet
      },
      data() {
        return {
            professionnel: {},
            map1: null,
            tileLayer: null,
        }
      },
        methods: {
        initMap() {
            this.map1 = L.map('imap1').setView([47.413220, -1.219482], 12)
            this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                      //'https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}.png',
            {
                maxZoom: 18,
                center: [47.413220, -1.219482],
                attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, &copy; <a href="https://carto.com/attribution">CARTO</a>',
            }).addTo(this.map1)

 L.marker([47.413220, -1.219482]).addTo(this.map1).bindPopup('name')
                        .openPopup()

 this.map1.invalidateSize()

  })
 },
},
created () {
 this.initMap()
}

}
</script>

1 回答

  • 1

    使用mounted生命周期钩子而不是created .

    created 通常是订阅一些数据/启动一些异步进程,而 mounted 则是在你的组件的DOM准备就绪时(但不一定在页面IIRC中引入) .

    然后,如Data-toggle tab does not download Leaflet map中所述,您必须使用invalidateSize after 打开包含Map容器的Tab,即您必须收听一个表示您的用户已打开Tab的事件 .

    对于Bootstrap-Vue,您有 <b-tabs>"input"事件,但仅在用户单击Tab时发出信号 . 但后者仍未开放 . 因此,在调用 invalidateSize 之前,您必须给它一个短暂的延迟(通常使用setTimeout):

    Vue.use(bootstrapVue);
    
    Vue.component('imap', {
      template: '#imap',
      methods: {
        resizeMap() {
          if (this.map1) {
            this.map1.invalidateSize();
            // Workaround to re-open popups at their correct position.
            this.map1.eachLayer((layer) => {
              if (layer instanceof L.Marker) {
                layer.openPopup();
              }
            });
          }
        },
        initMap() {
          this.map1 = L.map('imap1').setView([47.413220, -1.219482], 12)
          this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 18,
            center: [47.413220, -1.219482],
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
          }).addTo(this.map1)
    
          L.marker([47.413220, -1.219482]).addTo(this.map1).bindPopup('name')
            .openPopup() // Opening the popup while the map is incorrectly sized seems to place it at an incorrect position.
        },
      },
      mounted() {
        this.initMap()
      },
    });
    
    new Vue({
      el: '#app',
      methods: {
        checkMap(tab_index) {
          if (tab_index === 1) {
            // Unfortunately the "input" event occurs when user clicks
            // on the tab, but the latter is still not opened yet.
            // Therefore we have to wait a short delay to allow the
            // the tab to appear and the #imap1 element to have its final size.
            setTimeout(() => {
              this.$refs.mapComponent.resizeMap();
            }, 0); // 0ms seems enough to execute resize after tab opens.
          }
        }
      },
    });
    
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
    <script src="https://unpkg.com/vue@2"></script>
    <link rel="stylesheet" href="https://unpkg.com/bootstrap@4/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" />
    <script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.js"></script>
    
    <div id="app">
      <!-- https://bootstrap-vue.js.org/docs/components/tabs -->
      <b-tabs @input="checkMap">
        <b-tab title="First Tab" active>
          <br>I'm the first fading tab
        </b-tab>
        <b-tab title="Second Tab with Map">
          <imap ref="mapComponent"></imap>
        </b-tab>
      </b-tabs>
    </div>
    
    <template id="imap">
      <div id="imap1" style="height: 130px;"></div>
    </template>
    

相关问题