Листовка не загружается во вкладку Bulma с помощью Vue.js
У меня проблема с загрузкой карты Leaflet с использованием компонентов вкладки Vue.js и Bulma (через Buefy).
Если карта находится внутри вкладки, она не загружает все плитки, пока размер окна браузера не изменится.
Если карта размещена вне компонента вкладок Bulma, она загружается без проблем.
призвание map.invalidateSize()
кажется, помогает, но чтобы сделать это автоматически, когда вкладка меняется, я должен вызвать его с помощью setTimeout
и поставить очень большую задержку, как 1 сек - что очень некрасиво.
Как заставить это работать без этого invalidateSize
обходной путь?
Пример с проблемой: https://codepen.io/alxxnder/pen/zyYxwd
Пример без проблемы: https://codepen.io/alxxnder/pen/LMYEjr
Код:
new Vue({
el: '#app',
data: {
map: null,
},
methods: {
invalidateSize: function() {
this.map.invalidateSize();
}
},
mounted() {
this.map = L.map('map').setView([38.63, -90.23], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Leaflet Test</title>
<link rel="stylesheet" href="https://unpkg.com/buefy@0.7/dist/buefy.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css">
</head>
<body>
<div class="section">
<div class="container" id="app">
<b-tabs position="is-centered">
<b-tab-item label="Tab 1">
<div class="section">
Tab 1
<div class="map" id="map" style="height: 400px; width: 100%"></div>
<button class="button is-info" @click="invalidateSize()">invalidateSize</button>
</div>
</b-tab-item>
<b-tab-item label="Tab 2">
<div class="section">
Tab 2
</div>
</b-tab-item>
</b-tabs>
</div>
</div>
</body>
<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/buefy@0.7/dist/buefy.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>
</html>
1 ответ
Как объясняется на вкладке "Переключение данных", не загружается карта листовок, проблема вызвана тем, что контейнер вашей карты еще не имеет своего полного размера при инициализации. Вы можете понять это легче, если ваша карта была на изначально скрытой вкладке (например, на вкладке 2).
Что касается вашей изначально активной вкладки (то есть вкладки 1), вполне вероятно, что Buefy / Bulma все еще требуется некоторое время для раскрытия содержимого вкладки.
Поскольку по завершении перехода по вкладке события не происходят, вы должны дождаться продолжительности перехода, прежде чем вызывать invalidateSize
метод. В твоем случае 300 мс вроде бы нормально.
Затем вы должны также вызвать его снова, когда пользователь меняет вкладку(см. События вкладок Buefy), в противном случае, если браузер изменил размер, когда ваша вкладка была скрыта, такая же проблема возникла бы снова.
Демо с картами в 2 вкладках:
new Vue({
el: '#app',
data: {
map: null,
map2: null,
tabMaps: []
},
methods: {
invalidateSize: function(tabIndex) {
setTimeout(() => {
if (typeof tabIndex === "number") {
this.tabMaps[tabIndex].invalidateSize();
} else {
// invalidate all maps
this.tabMaps.forEach(map => {
map.invalidateSize();
});
}
}, 300);
}
},
mounted() {
this.map = L.map('map').setView([38.63, -90.23], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
// map2 in tab2
this.map2 = L.map(this.$refs.map2).setView([38.63, -90.23], 12);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(
this.map2
);
this.tabMaps.push(this.map); // 0
this.tabMaps.push(this.map2); // 1
this.invalidateSize();
}
})
<link rel="stylesheet" href="https://unpkg.com/buefy@0.7/dist/buefy.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css">
<div class="section">
<div class="container" id="app">
<b-tabs @change="invalidateSize" position="is-centered">
<b-tab-item label="Tab 1">
<div class="section">
Tab 1
<div class="map" id="map" style="height: 400px; width: 100%"></div>
<button class="button is-info" @click="invalidateSize()">invalidateSize</button>
</div>
</b-tab-item>
<b-tab-item label="Tab 2">
<div class="section">
Tab 2
<div class="map" ref="map2" style="height: 400px; width: 100%"></div>
</div>
</b-tab-item>
</b-tabs>
</div>
</div>
<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/buefy@0.7/dist/buefy.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>