【问题标题】:Vue2-leaflet map not showing properly in BoostrapVue modalVue2 传单地图在 BoostrapVue 模态中未正确显示
【发布时间】:2019-10-15 06:37:46
【问题描述】:

这是我的问题 - Vue2 传单地图无法在 BootstrapVue 模态中正确呈现。

这是它的视觉外观(它应该只显示海洋)

<template>
  <div>
    <b-modal size="lg" :visible="visible" @hidden="$emit('clear')" title="Event details">
      <div class="foobar1">
        <l-map :center="center" :zoom="13" ref="mymap">
          <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
          <l-marker :lat-lng="center"></l-marker>
        </l-map>
      </div>

      <template slot="modal-footer">
        <b-btn variant="danger" @click="deleteEventLocal(event.id)">Delete</b-btn>
      </template>
    </b-modal>
  </div>
</template>

<script>
import * as moment from "moment";
import { LMap, LMarker, LTileLayer } from "vue2-leaflet";
import { deleteEvent } from "./api";
import "vue-weather-widget/dist/css/vue-weather-widget.css";
import VueWeatherWidget from "vue-weather-widget";

export default {
  data() {
    return {
      center: L.latLng(event.latitude, event.longitude),
      url: "http://{s}.tile.osm.org/{z}/{x}/{y}.png",
      attribution:
        '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    };
  },
  props: {
    visible: {
      type: Boolean
    },
    event: {
      required: true,
      type: Object
    }
  },
  methods: {
    async deleteEventLocal(id) {
      await deleteEvent(id);
      this.$emit("refresh");
      this.$emit("clear");
    }
  },
  components: {
    weather: VueWeatherWidget,
    LMap,
    LMarker,
    LTileLayer
  }
};
</script>

正如您所见,没有任何 CSS 规则可以使地图像它那样溢出到模态框之外。这很奇怪。

我有点问这个问题自己来回答,因为我以前找不到解决方案。

【问题讨论】:

    标签: vue.js bootstrap-4 vuejs2 leaflet vue2leaflet


    【解决方案1】:

    发生这种情况的原因有 3 个。

    1. 首先 - 我忘记将传单 css 加载到 main.js - 这就是为什么传单地图不知何故超出了模式。

    //src/main.js
    import '@babel/polyfill';
    import Vue from 'vue';
    import './plugins/bootstrap-vue';
    import App from './App.vue';
    import router from './router';
    import store from './store';
    //above imports not important to this answer
    
    import 'leaflet/dist/leaflet.css'; //<--------------add this line
    
    new Vue({
      router,
      store,
      render: h => h(App),
    }).$mount('#app');
    

    2. 现在地图可能会消失。在l-map 组件的容器上设置宽度和高度。我使用了一个类,但你可以使用 style="" 等。

    <div class="foobar1"> <!-- <--- Add a class on l-map's container -->
      <l-map :center="center" :zoom="13">
        <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
        <l-marker :lat-lng="center"></l-marker>
      </l-map>
    </div>
    
    <style lang="scss">
      .foobar1 { /* <--- class we added above */
        width: 100%;
        height: 400px;
      }
    </style>
    

    3. 现在您的地图将在模式中呈现,但如果您移动地图的视图,您会看到传单没有及时下载地图的方块。 你会看到这样的东西:

    解决这个问题:

    • b-modal 上为@shown 事件创建一个事件处理程序。

       <b-modal
         @shown="modalShown"
      
      
         @hidden="$emit('clear')"
         size="lg"
         :visible="visible"
         title="Event details"
       >
      

      我打电话给我的modalShown

    • 然后,将ref 属性添加到您的l-map。我打电话给我的mymap

      <l-map :center="center" :zoom="13" ref="mymap"> <!-- ref attribute added to l-map -->
        <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
        <l-marker :lat-lng="center"></l-marker>
      </l-map>
      
    • 然后,在 Vue 方法中为您的视图/组件创建一个 modalShown 方法,并在其中调用 invalidateSize()

      export default {
        data() {
         //some data here
        }
      
        methods: {
           modalShown() {
            setTimeout(() => {
              //mapObject is a property that is part of leaflet
              this.$refs.mymap.mapObject.invalidateSize(); 
            }, 100);
          }
        }
      }
      

    现在一切都会好起来的:

    • 地图不应溢出到模式之外
    • 地图应该是可见的(呃)
    • 应在地图正文中下载地图方块

    Here's my full code, it contains some stuff specific to my app but overall it contains all of the code snippets above.

    【讨论】:

    • 很好的说明!至于invalidateSize()的解释:stackoverflow.com/questions/36246815/…
    • 谢谢老兄在过去的 2 个小时里一直把我的头撞在显示器上,试图找出地图损坏的原因
    【解决方案2】:

    Artur Tagisow 答案的补充

    如果您的地图在子组件中,您也可以对父组件使用这种方法。

    export default {
      data() {
       //some data here
      }
    
      methods: {
         modalShown() {
          setTimeout(() => {
            window.dispatchEvent(new Event("resize"));
          }, 100);
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      对于 vue.js 和 nuxt.js 开发者来说,可能是因为使用了 v-showv-if ! 在你的情况下,引导模式显示没有发生 但别担心,您唯一需要做的就是仅使用客户端(它类似于 ssr,但适用于新版本的 js 框架,如 nuxt 或 vue):

      <client-only>
      <div id="bootstrapModal">
      <div id="map-wrap" style="height: 100vh">
         <l-map :zoom=13 :center="[55.9464418,8.1277591]">
           <l-tile-layer url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"></l-tile-layer>
           <l-marker :lat-lng="[55.9464418,8.1277591]"></l-marker>
         </l-map>
       </div>
      </div>
      </client-only>
      

      ps:如果在 iphone 浏览器中仍未加载,可能是因为 地理位置

      【讨论】:

        猜你喜欢
        • 2013-12-22
        • 2017-03-14
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多