首页 > 解决方案 > 边界改变后清除标记,vue cookbook google map

问题描述

我有一个关于更新新边界后清除标记的问题。新标记被添加到地图中,但旧标记保持不动。这有点尴尬,因为每次我发布具有新边界的请求时,Vuex 状态都会更新......

我提供的参考是为了更好地理解 vue 食谱 和食谱的代码(不是我的代码,但非常相似。)

地图加载器.vue

在这里,我创建地图并毫无问题地请求边界。并且每次拖动地图时,我都会在 Vuex 的新数组中获取新标记。

<template>
    <div>
        <div class="google-map" ref="googleMap"></div>
        <template v-if="Boolean(this.google) && Boolean(this.map)">
            <slot
                :google="google"
                :map="map"
            />
        </template>       
    </div>
</template>
<script>
import GoogleMapsApiLoader from 'google-maps-api-loader'
import { mapGetters } from 'vuex'
export default {
    props: {
        mapConfig: Object,
        apiKey: String,
        info_and_center: Function,
    },

    data() {
        return {
            google: null,
            map: null
        }
    },

    async mounted() {
        const googleMapApi = await GoogleMapsApiLoader({
            apiKey: this.apiKey
        })
        this.google = googleMapApi
        this.initializeMap()
    },
    watch:{
        mapConfig(old_ad, new_ad){
            this.initializeMap()
        }
    },
    methods: {
        initializeMap() {
            const mapContainer = this.$refs.googleMap
            this.map = new this.google.maps.Map(
                mapContainer, this.mapConfig
            )     

            let self = this;

            this.google.maps.event.addListener((this.map), 'idle', function(event) {
                self.get_markers();
            });
        },
        get_markers(){
            let bounds = this.map.getBounds();
            let south_west = bounds.getSouthWest();
            let north_east = bounds.getNorthEast();

            let payload = {
                "from_lat": south_west.lat(),
                "to_lat": north_east.lat(),
                "from_lng": south_west.lng(),
                "to_lng": north_east.lng(),
            }

            // manually clearing the array of markers
            this.$store.state.project.projects = []
            console.log(this.get_projects)
            // it's cleared

            this.$store.dispatch("load_projects_by_coords", payload)
        },
    },
    computed: {
        ...mapGetters([
            "get_projects"
        ])
    }
}
</script>

更新

通常我不需要这样做,但在get_markers()我编写代码之前清除get_projectsdispatch但仍然旧标记保持静止。

地图.vue

<template>
    <GoogleMapLoader
        :mapConfig="mapConfig"
        apiKey="my_key"
    >
        <template slot-scope="{ google, map}">
            <GoogleMapMarker
                v-for="marker in get_projects"
                :key="marker.id"
                :marker="marker"
                :google="google"
                :map="map"
            />
        </template>
    </GoogleMapLoader>
</template>
<script>
import GoogleMapLoader from './google-map-loader'
import GoogleMapMarker from './google-map-marker'
import { mapSettings } from './helpers/map-setting'
import { mapGetters } from "vuex";

export default {
    components: {
        GoogleMapLoader,
        GoogleMapMarker,
    },

    computed: {
        ...mapGetters([
            "get_projects",
            "get_search_address_lat",
            "get_search_address_lng",
        ]),
        mapConfig () {
            return {
                ...mapSettings,
                center: this.mapCenter
            }
        },
        mapCenter () {
            return {lat: this.get_search_address_lat, lng: this.get_search_address_lng}
        },
    },
}

如您所见,我正在迭代内部的新标记,get_projects没有任何问题。但是旧标记保持不动,尽管在console.log(this.get_projects)边界改变后我只有新标记在那里。所以问题是如何使用新标记更新地图?

标记.vue

<script>
export default {
    props: {
        google: {
            type: Object,
            required: true
        },
        map: {
            type: Object,
            required: true
        },
        marker: {
            type: Object,
            required: true
        },
    },
    mounted() {

        let marker = new this.google.maps.Marker({
            position: this.marker,
            marker: this.marker,
            map: this.map,
        })

        var contentString = "test";

        var infowindow = new this.google.maps.InfoWindow({
            content: contentString
        });

        this.google.maps.event.addListener(marker, 'click', function() {
            this.map.setCenter(marker.getPosition());
            infowindow.setContent(contentString);
            infowindow.open(this.map, marker);
        });
    },
    render(){},
}
</script>

标签: javascriptgoogle-mapsvue.js

解决方案


我以前没有使用过这个 API。但是我看到您发布的食谱链接中没有涵盖删除标记。我认为正在发生的事情是您在挂载时注册了一个新标记,这当然很好,但是当组件被销毁时您不会删除它。

文档说要在 to null 上使用,setMap以便Marker将其删除。因此,如果您保留对钩子中创建的标记的引用,则mounted可以在钩子中将其删除beforeDestroy

GoogleMapMarker.vue

  data: () => ({
    mapMarker: null
  }),

  mounted() {
    const { Marker } = this.google.maps;

    this.mapMarker = new Marker({
      position: this.marker.position,
      marker: this.marker,
      map: this.map,
      icon: POINT_MARKER_ICON_CONFIG
    });
  },

  beforeDestroy() {
    this.mapMarker.setMap(null);
  },

附言。let self = this;是不必要的。

let self = this;

this.google.maps.event.addListener((this.map), 'idle', function(event) {
    self.get_markers();
});

匿名函数:

this.google.maps.event.addListener((this.map), 'idle', event => {
    this.get_markers();
});

推荐阅读