【问题标题】:Need to dynamically refresh map in Vue component需要在Vue组件中动态刷新地图
【发布时间】:2018-10-04 07:52:41
【问题描述】:

我有一个可以执行以下操作的工作组件:

  • 通过created() 中的全局总线方法从同级输入组件接收字符串 => 有效
  • 通过geoDecoding() 将字符串处理成纬度/经度坐标 => works
  • 解析promise结果坐标,设置数据,也可以通过geoDecoding() => 工作
  • 在事件触发后使用更改的数据刷新showMap() => 不起作用 :(

请注意,我有带有硬编码默认值的道具(已注释掉),只是为了检查 showMap() 与这些值,它可以工作。

  • 我在showMap() 上设置了一个调试器,我注意到纬度和经度没有设置,这很奇怪,因为我将它们设置在created() 下调用geoDecoding()

我想让showMap() 刷新每个触发的事件,它会从this.latLong.latitude / this.latLong.longitude 获取刷新的数据()并根据这些新值重新实例化地图。在目前这一点上,并在此处粘贴此代码实例,我得到 showMap() 来建立地图但地图是空的,因为它没有从 geoDecoding() 接收纬度/经度。

代码:

<template>
    <div class="map-container" :id="theMap"></div>
</template>

<script>
    import { Bus } from "../main";

    export default {
        name: "GoogleMapsContainer",
        data() {
            return {
                theMap: "map-for-" + this.name,
                location: '',
                latLong: {
                    latitude: '',
                    longitude: ''
                },
            }
        },
        props: {
            name,
            // 'latitude': {
            //     type: Number,
            //     default: function () {
            //         return 39.50
            //     }
            // },
            // 'longitude': {
            //     type: Number,
            //     default: function () {
            //         return -98.35
            //     }
            // },
            // 'zoom': {
            //     type: Number,
            //     default: function () {
            //         return 4
            //     }
            // }
        },
        methods: {
            showMap() {
                debugger;
                this.map = new google.maps.Map(document.getElementById(this.theMap), {
                    center: {lat: this.latLong.latitude, lng: this.latLong.longitude},

                    zoom: this.zoom
                });
            },
            geoDecoding() {
                let geocoder = new google.maps.Geocoder();
                let theLocation = this.location;
                let latLong = this.latLong;

                    return new Promise(function (resolve, reject) {
                        geocoder.geocode({'address': (theLocation ? theLocation : 'canada')}, function (results, status) {
                            console.log(results);
                            if (status === google.maps.GeocoderStatus.OK) {
                                console.log(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                                latLong.latitude = results[0].geometry.location.lat();
                                latLong.longitude = results[0].geometry.location.lng();
                            } else {
                                reject(status);
                            }
                        });
                    });
            }
        },
        mounted() {
            //this.geoDecoding();
            this.showMap();

        },
        created() {
            this.geoDecoding();
            Bus.$on('passLocation', (input) => {
                this.location = input;
                this.geoDecoding();
            });
        },


    }
</script>

<style scoped>
    .map-container {
        width: 80vw;
        margin: 5vh auto;
        height: 50vh;
        background: fuchsia;
    }
</style>

【问题讨论】:

  • 你能提供一个Minimal, Complete, and Verifiable example吗?例如,使用codesandbox
  • @MarcoPantaleoni - 只需获取一个 API 密钥并将其放入 index.html App.vue 实际上只是将这个组件包装在上面,然后输入 $emits 一个输入,没什么特别的。您已经有一份清单中列出的有效/无效的东西。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

您需要在latLong 上使用观察者:

  watch: {
    latLong: {
      handler: function(val, oldVal) {
        this.showMap();
      },
      deep: true
    }
  },

【讨论】:

    【解决方案2】:

    我发现执行此操作的方式是使用 Google 的 API 代码:

    panTo(&lt;your-lat-lng-coords&gt;);

    要将其合并到您的代码中,这将在异步调用期间设置。

    我的承诺在methods:{geoDecoding(){}}如下:

    geoDecoding() {
        let geocoder = new google.maps.Geocoder();
        let theLocation = this.location;
        let latLong = this.latLong;
        self = this;
    
        let service = new google.maps.places.PlacesService(this.map);
        var erez_markers = [];
    
        return new Promise(function (resolve, reject) {
            geocoder.geocode({'address': theLocation}, function (results, status) {
                if (status === google.maps.GeocoderStatus.OK) {
                    console.log(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                    latLong.latitude = results[0].geometry.location.lat();
                    latLong.longitude = results[0].geometry.location.lng();
                    this.myLatlng = new google.maps.LatLng(latLong.latitude, latLong.longitude);
                    self.map.panTo(this.myLatlng);//******* this would shift map on every instantiation with new lat/lng's
                } else {
                    reject(status);
                }
            });
        });
    }
    

    我的状态数据设置为默认值,因此地图会在初始化时返回一些内容,如下所示:

    latLong: {
        latitude: 43.6532,
        longitude: -79.3832
    },
    location: '',
    zoom: '',
    

    显示地图将在全局范围内设置,因此我们可以从任何位置调用/重新实例化它。我已经在methods:{showmap(){}}下设置了

    this.map = new google.maps.Map(document.getElementById(this.theMap), {
                        center: {lat: this.latLong.latitude, lng: this.latLong.longitude},
                        zoom: this.zoom
    });
    

    【讨论】:

      猜你喜欢
      • 2021-10-10
      • 2021-04-25
      • 2019-10-16
      • 2021-07-31
      • 1970-01-01
      • 2016-06-22
      • 2019-01-23
      • 1970-01-01
      • 2018-10-01
      相关资源
      最近更新 更多