Vue3 Google Maps 标记无法移除
Posted
技术标签:
【中文标题】Vue3 Google Maps 标记无法移除【英文标题】:Vue3 Google Maps marker cannot be removed 【发布时间】:2021-12-26 08:50:59 【问题描述】:我有一个大部分功能的自制系统,用于在 Vue3 中处理谷歌地图。我没有使用库,因为没有一个库具有我想要的功能(最终),而且我自己实现似乎相对简单(直到本期为止)。
Map组件如下:
<template>
<div class="map-container">
<div class="google-map" ref="map"></div>
<div>
<slot></slot>
</div>
</div>
</template>
<script>
import Loader from '@googlemaps/js-api-loader';
export default
props:
latitude:
type: [String, Number],
default: 0
,
longitude:
type: [String, Number],
default: 0
,
zoom:
type: Number,
default: 15
,
,
data()
return
map: null,
api: null,
move: null,
,
provide: function ()
return
getMap: this.getMap
,
watch:
latitude() this.updateCenter() ,
longitude() this.updateCenter()
,
methods:
getMap(callback)
var self = this;
function checkForMap()
if (self.map)
callback(self.map, self.api);
else
setTimeout(checkForMap, 50);
checkForMap();
,
updateCenter()
let center = new this.api.LatLng(this.latitude, this.longitude);
this.map.panTo(center);
,
mounted()
let self = this
let apiKey = document.getElementById('GOOGLE_MAPS_KEY').value
let loader = new Loader(
apiKey: apiKey,
version: "weekly",
libraries: ["geometry"]
);
loader.load()
.then((google) =>
self.api = google.maps;
self.map = new google.maps.Map(self.$refs.map,
center:
lat: parseFloat(self.latitude),
lng: parseFloat(self.longitude)
,
zoom: self.zoom,
disableDefaultUI: true,
);
// Configure the click listener.
self.map.addListener("click", (mapsMouseEvent) =>
self.$emit('click', mapsMouseEvent)
);
// Configure the move listener.
self.map.addListener("bounds_changed", () =>
if(self.move) clearTimeout(self.move);
self.move = setTimeout(() =>
let bounds = self.map.getBounds(true);
let center = self.map.getCenter();
let radius = 100000;
if(bounds && center)
let northEast = bounds.getNorthEast();
radius = self.api.geometry.spherical.computeDistanceBetween(center, northEast);
self.$emit('move',
bounds: bounds,
radius: Math.round(radius),
center:
latitude: center.lat(),
longitude: center.lng()
)
, 800);
);
)
.catch(e => );
</script>
而标记组件如下:
<template>
<div></div>
</template>
<script>
export default
props:
latitude: String,
longitude: String,
icon:
type: String,
default: '/images/pin.png'
,
data()
return
map: null,
api: null,
marker: null
,
inject: ["getMap"],
watch:
latitude() this.updatePosition() ,
longitude() this.updatePosition()
,
mounted()
let self = this
this.getMap(function(map, api)
self.map = map;
self.api = api;
self.marker = new api.Marker(
position: new api.LatLng(self.latitude, self.longitude),
map: map,
icon: self.icon,
);
self.marker.addListener("click", () =>
self.$emit('click', self.marker)
);
)
,
beforeUnmount()
this.marker.setMap(null);
this.marker = null;
,
methods:
updatePosition()
this.marker.setPosition( new this.api.LatLng( parseFloat(this.latitude), parseFloat(this.longitude) ) );
</script>
然后我有一个组件,它使用这些组件来显示带有标记的地图。
<template>
<div>
<div class="admin-site-map">
<google-map :center="center" :zoom="15">
<map-marker v-for="site in sites" :key="site.id"
:latitude="site.latitude"
:longitude="site.longitude"
@click="markerClicked"
/>
</google-map>
</div>
</div>
</template>
<script>
import GoogleMap from '@/components/Core/Maps/GoogleMap';
import Marker from '@/components/Core/Maps/Marker';
export default
components: GoogleMap, mapMarker: Marker ,
props: ['sites'],
data()
return
center: lat: 0, lng: 0,
,
methods:
markerClicked(value)
console.log('click: ', value)
</script>
当标记(站点)列表发生变化时,我可以看到在已删除的标记上调用了beforeUnmount
方法,但标记并没有从地图上消失,我什至仍然可以单击标记并接收事件中发出的null
值。
奇怪的是,调用 this.marker.setVisible(false)
确实有效,并隐藏了标记。
我已经坚持了一段时间,所以任何见解或帮助将不胜感激。谢谢!
【问题讨论】:
我无法复制this(稍作修改的版本)。我建议您尝试逐段删除代码(不相关的方法,观察者,...),直到它起作用为止。 【参考方案1】:感谢User28,我终于找到了解决方案:
在标记组件上,marker
(Google 标记对象保存到的位置)不应是反应性属性。将数据方法更改为
return
map: null,
api: null
修复了问题(即删除marker
)。
【讨论】:
以上是关于Vue3 Google Maps 标记无法移除的主要内容,如果未能解决你的问题,请参考以下文章