Vue2 传单地图在 BoostrapVue 模态中未正确显示

Posted

技术标签:

【中文标题】Vue2 传单地图在 BoostrapVue 模态中未正确显示【英文标题】:Vue2-leaflet map not showing properly in BoostrapVue modal 【发布时间】: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 规则可以使地图像它那样溢出到模态框之外。这很奇怪。

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

【问题讨论】:

【参考方案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()的解释:***.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 ! 在你的情况下,引导模式显示没有发生 但别担心,您唯一需要做的就是仅使用客户端(它类似于 s-s-r,但适用于新版本的 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 浏览器中仍未加载,可能是因为 地理位置

【讨论】:

以上是关于Vue2 传单地图在 BoostrapVue 模态中未正确显示的主要内容,如果未能解决你的问题,请参考以下文章

传单不显示地图

如何在 R 的传单地图中删除属性

传单地图双标问题

在容器调整大小时调整传单地图的大小

传单地图宽度(以米为单位)

将地图从列表行传单地图拖动到选定的标记