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:
'© <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-show 或 v-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 模态中未正确显示的主要内容,如果未能解决你的问题,请参考以下文章