VueJS:Google Maps在数据准备就绪之前先加载-如何使其等待?(Nuxt)

这是我第VueJS项目,我已经得到了vue2,谷歌,地图和运行,但我遇到一个问题,当我尝试地图标记连接到我的网站的JSON饲料(使用WordPress的REST API),该纬度Lng值返回undefinedNaN

经过进一步的调查(由于下面的@QuỳnhNguyễn),似乎在数据准备就绪之前正在运行Google Maps实例。我已尝试在初始化地图之前查看要加载的供稿,但是它似乎不起作用。

标记位置使用JSON从WordPress REST API中提取,并存在于数组(位置)中。该阵列存在并已在Vue Dev Tools中填充(51条记录),但是在mount上检查时,该阵列为空。数据是在创建的阶段提取的,所以我不知道为什么安装阶段无法准备好数据。

有问题的代码如下...

模板:

<template>
    <gmap-map v-if="feedLoaded" ref="map" :center="center" :zoom="zoom" :map-type-id="mapTypeId" :options="options">
        <gmap-marker 
            :key="index" v-for="(m, index) in locations" 
            :position="{ lat: parseFloat(m.place_latitude), lng: parseFloat(m.place_longitude) }" 
            @click="toggleInfoWindow(m,index)" 
            :icon="mapIconDestination">
        </gmap-marker>
        <gmap-info-window></gmap-info-window>
    </gmap-map>
</template>

脚本

<script>
    const axios = require('axios');
    const feedURL = "API_REF";

    export default {
        props: {
            centerRef: {
                type: Object,
                default: function() {
                    return { lat: -20.646378400026226, lng: 116.80669825605469 }
                }
            },
            zoomVal: {
               type: Number,
               default: function() {
                   return 11
               }
            }
        },
        data: function() {
            return {
                feedLoaded: false,
                zoom: this.zoomVal,
                center: this.centerRef,
                options: {
                    mapTypeControl: false,
                    streetViewControl: false,
                },
                mapTypeId: 'styledMapType',
                mapIconDestination: '/images/map-pin_destination.png',
                mapIconActivity: '/images/map-pin_activity.png',
                mapIconAccommodation: '/images/map-pin_accommodation.png',
                mapIconEvent: '/images/map-pin_event.png',
                mapIconBusiness: '/images/map-pin_business.png',
                locations: [],
                markers: []
            }
        },
        created: function() {
            this.getData();
        },
        mounted: function() {
            this.$nextTick(() => {
                this.$refs.karrathaMap.$mapPromise.then((map) => {
                    var styledMapType = new google.maps.StyledMapType(
                        [...MAP_STYLE SETTINGS...]
                    )
                    map.mapTypes.set('styled_map', styledMapType);
                    map.setMapTypeId('styled_map');

                })

            });
        },
        watch: {
            feedLoaded: function() {
                if (this.feedLoaded == true) {
                    console.log(JSON.stringify(this.locations))
                }
            }
        },
        methods: {
            getData() {
                const url = feedURL;
                axios
                    .get(url)
                    .then((response) => {this.locations = response.data;})
                    .then(this.feedLoaded = true)
                    .catch( error => { console.log(error); }
                );
            }
        }
    }
</script>
飞云路易2020/03/23 10:58:14

vuejs在元素上支持v-if指令。我建议您尝试使用以下代码段。

<template>
  <div id="map" v-if="loaded">
    <gmap-map ref="map" :center="center" :zoom="zoom" :map-type-id="mapTypeId" :options="options">
      <gmap-marker
        :key="index" v-for="(m, index) in locations"
        :position="{ lat: parseFloat(m.place_latitude), lng: parseFloat(m.place_longitude) }"
        @click="toggleInfoWindow(m,index)"
        :icon="mapIconDestination">
      </gmap-marker>
      <gmap-info-window></gmap-info-window>
    </gmap-map>
  </div>
</template>


<script>
  export default {
    data() {
      return {
        loaded: false
      }
    },
    beforeMount: function () {
      const url = feedURL;
      axios
        .get(url)
        .then((response) => {
          this.locations = response.data;
          //activate element after api call response recieved
          this.loaded = true
        })
        .catch(error => {
            console.log(error);
          }
        );
    }
  }

</script>
宝儿理查德2020/03/23 10:58:14

它似乎与数据格式有关。vue-devtools提供的屏幕截图您的数据是从WordPress的REST API在下面的格式返回:

[
  {
    "acf": {
      "place_latitude": "-22.695754",
      "place_longitude": "118.269081",
      "place_short-description": "Karijini National Park"
    },
    "id": 12,
    "parent": 10,
    "title": {
      "rendered": "Karijini National Park"
    }
  },
  ... 
]

具有如何locations初始化数组的getData方法方法),可以像这样传递position属性:

<gmap-marker
    :key="index"
    v-for="(m, index) in locations"
    :position="{ lat: parseFloat(m.acf.place_latitude), lng: parseFloat(m.acf.place_longitude) }"
></gmap-marker>

这是一个演示