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

Art*_*sow 3 javascript css leaflet vue.js bootstrap-4

这是我的问题-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>
Run Code Online (Sandbox Code Playgroud)

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

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

Art*_*sow 7

由于这有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');
Run Code Online (Sandbox Code Playgroud)
  1. 现在,地图可能会消失。在l-map组件的容器上设置宽度和高度。
//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');
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
  1. 现在,您的地图将在模态中渲染,但是如果您移动地图的视图,您将看到该传单没有及时下载地图的正方形。您将看到如下内容: 修复CSS之后出现模式,但没有invalidateSize()修复

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

<style lang="scss">
.foobar1 {
  width: 100%;
  height: 400px;
}
</style>
Run Code Online (Sandbox Code Playgroud)

我打电话给我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>
Run Code Online (Sandbox Code Playgroud)

然后modalShown在Vue方法中为您的视图/组件创建一个方法并invalidateSize()在内部调用。我不知道为什么会这样。invalidateSize本机Leaflet API的一部分vue2leaflet只是一个包装器),我们在此方法中调用它。

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

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

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

这是我的完整代码,其中包含一些特定于我的应用程序的内容,但总的来说,它包含上述所有代码段。