Vue2-传单地图在BoostrapVue模态中无法正确显示

时间:2019-05-29 15:35:39

标签: javascript css vue.js bootstrap-4 leaflet

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

这是视觉上的样子(应该只显示海洋)

enter image description here

<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规则可以像这样使地图溢出到模式之外。哪个很奇怪。

我有点想问这个问题,因为我以前找不到解决方案。

2 个答案:

答案 0 :(得分:3)

这是由于3个问题导致的。

  1. 首先-我忘了将传单css加载到main.js中-这就是为什么传单地图以某种方式超出模态的原因。
//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

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app');
  1. 现在地图可能会消失。在l-map组件的容器上设置宽度和高度。
<div class="foobar1">
  <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 {
  width: 100%;
  height: 400px;
}
</style>
  1. 现在,您的地图将在模态内渲染,但是如果您移动地图的视图,则会看到该传单没有及时下载地图的正方形。 您将看到如下内容: modal after fixing css but without invalidateSize() fix

要解决此问题,请在b-modal事件上为@shown创建一个事件处理程序。

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

我叫我的modalShown

然后,向您的ref添加一个l-map属性。我叫我的mymap

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

然后在Vue方法中为您的视图/组件创建一个modalShown方法,并在其中调用invalidateSize()。我不知道为什么会这样。 invalidateSizepart of native leaflet APIvue2leaflet is just a wrapper),我们在此方法中称呼它。

export default {
  data() {
   //some data here
  }

  methods: {
     modalShown() {
      setTimeout(() => {
        this.$refs.mymap.mapObject.invalidateSize(); 
      }, 100);
    }
  }
}

现在一切都应该没事了-地图不应溢出到模态之外,地图应该可见(duh),并且当地图方块在地图正文中时应下载地图方块。

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

答案 1 :(得分:0)

Artur Tagisow答案的补充

如果您的地图位于子组件中,您也可以对父组件使用此方法。

export default {
  data() {
   //some data here
  }

  methods: {
     modalShown() {
      setTimeout(() => {
        window.dispatchEvent(new Event("resize"));
      }, 100);
    }
  }
}