我有一个 Vue 组件,它使用代表公园的多边形渲染 Mapbox 地图(使用 @studiometa/vue-mapbox-gl 库)。当用户单击代表公园的多边形时,多边形的中心会显示一个弹出窗口。我的 Vue 组件看起来像这样(删除了我认为与问题无关的内容):
<script>
export default {
data() {
return {
parks: [ /** JSON objects */],
selectedPark: null
}
},
methods: {
mapLoaded(map) {
// Set up a popup to appear when the user clicks a park's polygon
map.on('click', 'parkPolygonsFill', (e) => {
this.parks.forEach((park) => {
if (park.id === e.features[0].properties.id) {
this.selectedPark = park;
console.log('new selected park', this.selectedPark);
}
});
});
},
}
}
</script>
<template>
<!-- Most attributes of these child components removed for brevity -->
<MapboxMap @mb-created="mapLoaded" />
<MapboxSource />
<MapboxLayer />
<!-- This is the component not behaving correctly -->
<MapboxPopup v-if="selectedPark"
:lng-lat="[selectedPark.longitude, selectedPark.latitude]">
<span>{{ selectedPark.name }}</span>
</MapboxPopup>
</template>
地图加载,当我单击地图上的多边形时,
MapboxPopup
正确呈现,并出现公园的弹出窗口。但是,当我单击不同的多边形时,弹出窗口消失了,我可以从开发人员工具中的 DOM 中看到 <MapboxPopup>
没有被渲染。没有控制台错误。奇怪的是,我确实有 new selected park
控制台日志和 this.selectedPark
中的正确公园。
为了调查,我将这个方法添加到我的 Vue 组件中:
popupForRandomPark() {
this.selectedPark = this.parks[Math.floor(Math.random()*this.parks.length)];
}
和模板中的一个按钮来调用它:
<button @click="popupForRandomPark">Open random popup</button>
我可以点击它一百万次,它可以完全正常地加载不同公园的弹出窗口,这表明
MapboxPopup
组件对新的 this.selectedPark
没有反应不是问题。
我觉得这与我在异步
this.selectedPark
事件处理程序中更改 map.on(...)
这一事实有关,但是 this.selectedPark
已正确登录到我的控制台,所以我有点没主意了?
假设在按钮上使用 vue 指令速记与 .on('click) 相比,会发生一些不同的交互。可以尝试添加 @click.prevent、self 或 $nextTick() 看看是否可以复制 map.on('click') 中发生的事情。