vue.js - 在调整屏幕大小之前,无法使用 VueJs 和传单在 DIV 上显示所有地图
问题描述
我正在使用 VueJS 和 Leaflet 来显示具有特殊本地化的地图。如文档中所述,我已在 index.html 上添加了 css 传单。
链接 rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css">
但我只有地图的一部分。我必须更改屏幕的大小才能使所有地图都带有标记。
这是我实现地图的vue(iMap.vue)
<template>
<div id="professionnel">
<b-row>
<b-tabs>
<b-tab title="A" >
<div>
<b-col class="col-12">
<div>Où nous joindre</div>
</b-col>
</div>
</b-tab>
<b-tab title="B">
<div class="tab-content-active" >
<b-col class="col-6">
<div>heure</div>
</b-col>
<b-col class="col-6 data_map">
<iMap1></iMap>
</b-col>
</div>
</b-tab>
</tabs>
</b-row>
</div>
</template>
<script>
import iMap1 from './iMap1'
export default {
name: 'professionnel',
components: {
iMap1
},
data() {
return {}
}
</script>
这是地图的vue(iMap.vue)
<template>
<div id="imap1" class="map" >
</div>
</template>
<script>
import leaflet from 'leaflet'
export default {
name: 'imap1',
components: {
leaflet
},
data() {
return {
professionnel: {},
map1: null,
tileLayer: null,
}
},
methods: {
initMap() {
this.map1 = L.map('imap1').setView([47.413220, -1.219482], 12)
this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
//'https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}.png',
{
maxZoom: 18,
center: [47.413220, -1.219482],
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attribution">CARTO</a>',
}).addTo(this.map1)
L.marker([47.413220, -1.219482]).addTo(this.map1).bindPopup('name')
.openPopup()
this.map1.invalidateSize()
})
},
},
created () {
this.initMap()
}
}
</script>
解决方案
created
通常是订阅一些数据/启动一些异步进程,而mounted
当您的组件的 DOM 准备好时(但不一定在页面 IIRC 中插入)。
然后,如Data-toggle tab does not download Leaflet map中所述,您必须在打开包含您的 Map 容器的 Tab之后使用,即您必须收听表明您的用户已打开 Tab 的事件。invalidateSize
在 Bootstrap-Vue 的情况下,您有<b-tabs>
'"input"
事件,但它仅在用户单击选项卡时发出信号。但是后者仍然没有打开。因此,您必须在调用之前给它一个短暂的延迟(通常使用setTimeout
)invalidateSize
:
Vue.use(bootstrapVue);
Vue.component('imap', {
template: '#imap',
methods: {
resizeMap() {
if (this.map1) {
this.map1.invalidateSize();
// Workaround to re-open popups at their correct position.
this.map1.eachLayer((layer) => {
if (layer instanceof L.Marker) {
layer.openPopup();
}
});
}
},
initMap() {
this.map1 = L.map('imap1').setView([47.413220, -1.219482], 12)
this.tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
center: [47.413220, -1.219482],
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(this.map1)
L.marker([47.413220, -1.219482]).addTo(this.map1).bindPopup('name')
.openPopup() // Opening the popup while the map is incorrectly sized seems to place it at an incorrect position.
},
},
mounted() {
this.initMap()
},
});
new Vue({
el: '#app',
methods: {
checkMap(tab_index) {
if (tab_index === 1) {
// Unfortunately the "input" event occurs when user clicks
// on the tab, but the latter is still not opened yet.
// Therefore we have to wait a short delay to allow the
// the tab to appear and the #imap1 element to have its final size.
setTimeout(() => {
this.$refs.mapComponent.resizeMap();
}, 0); // 0ms seems enough to execute resize after tab opens.
}
}
},
});
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="https://unpkg.com/vue@2"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4/dist/css/bootstrap.css" />
<link rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.js"></script>
<div id="app">
<!-- https://bootstrap-vue.js.org/docs/components/tabs -->
<b-tabs @input="checkMap">
<b-tab title="First Tab" active>
<br>I'm the first fading tab
</b-tab>
<b-tab title="Second Tab with Map">
<imap ref="mapComponent"></imap>
</b-tab>
</b-tabs>
</div>
<template id="imap">
<div id="imap1" style="height: 130px;"></div>
</template>
推荐阅读
- xcode - 无法在终端 macOS 10.15.7 上安装 cocoapods
- tensorflow - 为什么在张量流中应用 model.fit 时出现“'NoneType' object is not callable”错误?
- python - 为什么这个简单的输入代码会给出“SyntaxError: invalid syntax”?
- html - CSS / R闪亮:删除导航栏下方的填充
- c# - 将表加入实体框架中的列表
- python - 为什么我的 Django 应用程序无法读取环境变量集?
- python - 比较合并表中的多个列时出现 TypeError
- python - 如何让 demand_callback 考虑依赖于 ortools 中 to_node 的变量?
- android - 反应本机颜色问题
- parameters - 有没有办法将 Quicksight 电子邮件报告更新到今天的日期?