Vue.js & TypeScript로 구글 지도를 만드는 자체 제작 구성 요소

16972 단어 TypeScriptVue.js

배경


Vue.js에 구글 지도를 표시할 때도 기존 라이브러리vue2-google-maps를 사용하는 선택이 있었지만 앞으로 다양한 맞춤형 제작을 하고 싶은 상황에서 사용하기가 불편해 자제를 결정했다.
이번 설치 현황은 단지 내가 필요로 하는 기능일 뿐, 필요하면 추가 설치가 필요하다.

실시


GoogleMap


구글 지도에 사용되는 구성 요소.
GoogleMap.vue
<template>
  <div>
    <div id="googleMap" :style="`height:${height}`"></div>
    <template v-if="google && map">
      <slot :google="google" :map="map" />
    </template>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import qs from 'query-string'

const params = {
  key: 'Google API key',
  libraries: 'geometry,drawing,places',
  callback: 'handleLoadGoogleMapsScript'
}

interface GoogleMapWindow extends Window {
  handleLoadGoogleMapsScript: Function
  google: any
}

declare const window: GoogleMapWindow

@Component
export default class GoogleMap extends Vue {
  @Prop() private zoom!: number
  @Prop() private center!: { lat: number; lng: number }
  @Prop({ default: '240px' }) private height!: string
  google: any = null
  map: any = null

  mounted() {
    this.loadGoogleMapsScript().then(google => {
      this.google = google
      this.initializeMap()
    })
  }

  loadGoogleMapsScript() {
    return new Promise((resolve, reject) => {
      if (window.google) {
        return resolve(window.google)
      }
      const script = document.createElement('script')
      script.src = `https://maps.googleapis.com/maps/api/js?${qs.stringify(
        params
      )}`
      const head = document.querySelector('head')
      if (!head) return reject(new Error('head node is undefined'))
      head.appendChild(script)
      window.handleLoadGoogleMapsScript = () => {
        resolve(window.google)
      }
      setTimeout(() => {
        if (!window.google) {
          reject(new Error('failed load google api'))
        }
      }, 5000)
    })
  }

  initializeMap() {
    const mapContainer = this.$el.querySelector('#googleMap')
    const { Map, MapTypeId } = this.google.maps
    this.map = new Map(mapContainer, {
      zoom: this.zoom,
      center: this.center,
      mapTypeId: MapTypeId.ROADMAP
    })
  }
}
</script>

GoogleMapMarker


이것은 Goggle Map에 배치할 Marker의 구성 요소입니다.
추가 기능으로 을 클릭하면 정보가 표시됩니다.
GoogleMapMarker.vue
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'

@Component
export default class GoogleMapMarker extends Vue {
  @Prop() private google!: any
  @Prop() private map!: any
  @Prop() private position!: { lat: number; lng: number }
  @Prop() private title!: string
  marker: any
  infoWindow: any

  mounted() {
    const { Marker } = this.google.maps
    this.marker = new Marker({
      position: this.position,
      map: this.map
    })
    this.infoWindow = new this.google.maps.InfoWindow({
      content: `<div>${this.title}<div>`
    })
    this.google.maps.event.addListener(this.marker, 'click', () => {
      this.infoWindow.open(this.map, this.marker)
    })
  }
}
</script>

사용 예

<GoogleMap
  :zoom="17"
  :center="center"
  :height="240"
>
  <template slot-scope="scope">
    <GoogleMapMarker
      v-for="(marker, i) in markers"
      :key="i"
      :position="marker"
      :google="scope.google"
      :map="scope.map"
    />
  </template>
</GoogleMap>

예제 표시


배치된 태그가 클릭된 후 화면 스냅샷입니다.

참고 자료

좋은 웹페이지 즐겨찾기