如何使用VueJ在Google Maps中添加我的位置按钮?

时间:2018-07-18 15:05:38

标签: google-maps npm vue.js

如何使用Google MapsVueJs中添加我的位置按钮?

enter image description here

错误行:

 window.google.maps.event.addListener(this.map, 'center_changed', function () {
            secondChild.style['background-position'] = '0 0'})
  

无法读取未定义的属性“ center_changed”

this.map.controls[window.google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv)
  

无法读取未定义的属性“ 9”

代码

<template>
  <div>
     <gmap-map v-if='mostraMapa'
            :center='center'
            :zoom='20'
            map-type-id='terrain'
            style='width:100%;  height: 500px;'
            :options='{disableDefaultUI: true, zoomControl: true}'>
            <gmap-marker
               :position='marker.position'
               @click='center=marker.position'
               ref="map"
               ></gmap-marker>
         </gmap-map>
  </div>
</template>

<script>
export default {
  name: 'MeuMapa',
  props: ['mostraMapa'],
  data () {
    return {
      map: '',
      marker: '',
      center: { lat: -19.9191248, lng: -43.9386291 }
    }
  },
  created () {
    this.geolocate()
  },
  methods: {
    createMarker: function (latlng) {
      this.marker = new window.google.maps.Marker({
        setMap: this.map,
        position: latlng,
        animation: window.google.maps.Animation.DROP
      })
      this.addYourLocationButton()
    },
    geolocate: function () {
      navigator.geolocation.getCurrentPosition(position => {
        let latlng = new window.google.maps.LatLng(
          parseFloat(position.coords.latitude),
          parseFloat(position.coords.longitude))
        this.center = {
          lat: position.coords.latitude,
          lng: position.coords.longitude
        }
        this.createMarker(latlng)
      })
    },
    addYourLocationButton: function () {
      var controlDiv = document.createElement('div')

      var firstChild = document.createElement('button')
      firstChild.style.backgroundColor = '#fff'
      firstChild.style.border = 'none'
      firstChild.style.outline = 'none'
      firstChild.style.width = '28px'
      firstChild.style.height = '28px'
      firstChild.style.borderRadius = '2px'
      firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)'
      firstChild.style.cursor = 'pointer'
      firstChild.style.marginRight = '10px'
      firstChild.style.padding = '0px'
      firstChild.title = 'Your Location'
      controlDiv.appendChild(firstChild)

      var secondChild = document.createElement('div')
      secondChild.style.margin = '5px'
      secondChild.style.width = '18px'
      secondChild.style.height = '18px'
      secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-1x.png)'
      secondChild.style.backgroundSize = '180px 18px'
      secondChild.style.backgroundPosition = '0px 0px'
      secondChild.style.backgroundRepeat = 'no-repeat'
      secondChild.id = 'you_location_img'
      firstChild.appendChild(secondChild)

      window.google.maps.event.addListener(this.map, 'center_changed', function () {
        secondChild.style['background-position'] = '0 0'
      })
      firstChild.addEventListener('click', function () {
        var imgX = '0'
        var animationInterval = setInterval(function () {
          if (imgX === '-18') imgX = '0'
          else imgX = '-18'
          document.getElementById('you_location_img').style.backgroundPosition = '0px 0px'
        }, 500)
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(function (position) {
            var latlng = new window.google.maps.LatLng(position.coords.latitude, position.coords.longitude)
            this.marker.setPosition(latlng)
            this.map.setCenter(latlng)
            clearInterval(animationInterval)
            document.getElementById('you_location_img').style.backgroundPosition = '-144px 0px'
          })
        } else {
          clearInterval(animationInterval)
          document.getElementById('you_location_img').style.backgroundPosition = '0px 0px'
        }
      })

      controlDiv.index = 1
      this.map.controls[window.google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv)
    }
  }
}
</script>

<style>
</style>

1 个答案:

答案 0 :(得分:3)

您的this.map始终是空字符串,所以这就是您遇到这些错误的原因。您错误地使用了map对象,它需要设置正确的引用:

  1. ref="map"移至模板中的gmap-map标签。
  2. 将您的created钩子更改为mounted。使用以下代码:

    mounted () {
      // we need to be sure that child components are mounted
      // and can use refs inside this method.
      this.$nextTick(this.geolocate);
    },
    
  3. 如果使用vue2-google-maps,则将方法中的this.map替换为this.$refs.map.$mapObject

更新

在vue2-google-map文档中,我发现访问地图对象安全性需要与Promise配合使用

this.$refs.mapRef.$mapPromise.then((map) => {
  map.panTo({lat: 1.38, lng: 103.80})
})

但是在我的实例中没有看到$mapPromise,但是我使用的是最新版本。因此,我将其与内部另一个Promise $gmapApiPromiseLazy配合使用。

有一个可行的示例: jsfiddle