Около 6 месяцев назад мне понадобились Google Карты в моем приложении Vue, и я не мог найти подходящий пакет; так что я сделал свой (x5-gmaps). Пользователи часто спрашивают, как включить адресный поиск, поэтому вот простое руководство по этому поводу.

Результат: Репозиторий (код)

ОБНОВЛЕНО: это реализация последней версии: https://codesandbox.io/s/search-implementation-b53zt

Настраивать

Очень простая настройка с использованием Vue CLI и предустановок по умолчанию (Babel и ESLint).

Мы просто используем файл App.vue без компонентов (вы можете удалить все, кроме App.vue и main.js в src папка).

X5-gmaps (плагин Google Maps для Vue)

  1. Установить через npm install x5-gmaps
  2. Импортируйте и установите плагин в свой файл main.js:
// ...
import x5GMaps from 'x5-gmaps'
Vue.use(x5GMaps, { key: GOOGLE_KEY, libraries: ['places'] }
// ...

Карта

Настройка карты выполняется в App.vue, просто убедитесь, что контейнер компонента <gmaps-map/> имеет высоту:

<template>
  <div id="app">
    <gmaps-map />
  </div>
</template>
<script>
import { gmapsMap } from 'x5-gmaps'
export default {
  components: { gmapsMap }
}
</script>
<style>
body {
  margin: 0;
  padding: 0;
  height: 100vh;
}
#app {
  height: 100%;
}
</style>

Автозаполнение

Я начал с собственного руководства Google Автозаполнение поиска отелей, но для простоты убрал часть информации об отеле.

Как работает код Google: вы загружаете существующий элемент <input/> в Google Map API, и он превращает его в поле автозаполнения. Проблема в том, что для этого нам нужна ссылка на карту, а при открытии страницы карты нет (x5-gmaps запускает код для ее создания). Это сложная вещь с Google Maps и Vue, поэтому нам нужно прослушивать mounted событие <gmaps-map/>, которое дает нам карту для нашего ready() метода (который хранит и преобразует наш <input/>).

На этом этапе стоит добавить немного CSS в <input/>, чтобы он тоже располагался поверх карты:

<template>
  <div id="app">
    <gmaps-map @mounted="ready" />
    <input ref="autocomplete" id="autocomplete" placeholder="Search" />
  </div>
</template>
<script>
import { gmapsMap } from 'x5-gmaps'
export default {
  components: { gmapsMap },
  data: () => ({
    autocomplete: null,
    places: null,
    map: null
  }),
  methods: {
    ready(map) {
      this.map = map
      this.$GMaps().then((maps) => {
        this.places = new maps.places.PlacesService(map)     
        this.autocomplete = new maps.places.Autocomplete(this.$refs.autocomplete)
      })
    }
  }
}
</script>
<style>
/* ... */
#autocomplete {
  border: 10px solid rgba(0, 60, 255, 0.329);
  font-size: 18px;
  height: 40px;
  left: 40%;
  padding: 0 10px;
  position: absolute;
  top: 0;
  width: 20%;
  z-index: 1;
}
</style>

Используя это для чего-то

Итак, у вас должна быть видимая карта и автозаполнение; но это все равно бесполезно. Ради удовольствия, давайте добавим маркер, который перемещается (вместе с картой) туда, куда вы выберете.

Сначала добавим маркер. Мы просто используем компонент <gmaps-marker/> внутри нашего компонента <gmaps-map/> и даем ему необходимые данные о положении (markerPos) в форме реактивного свойства:

<template>
  <div id="app">
    <gmaps-map @mounted="ready">
      <gmaps-marker :position="markerPos" />
    </gmaps-map>
    <input ref="autocomplete" id="autocomplete" placeholder="Search" />
  </div>
</template>
<script>
import { gmapsMap, gmapsMarker } from 'x5-gmaps'
export default {
  components: { gmapsMap, gmapsMarker },
  data: () => ({
    autocomplete: null,
    places: null,
    map: null,
    markerPos: { lat: -27, lng: 153 }
  }),
...

Теперь нам нужно добавить слушателя для экземпляра Google Maps autocomplete, которому мы скармливали наш <input/>. Что касается метода, который мы очень скоро добавим (this.update), у нас теперь есть:

methods: {
    ready(map) {
      this.map = map
      this.$GMaps().then((maps) => {
        this.places = new maps.places.PlacesService(map)     
        this.autocomplete = new maps.places.Autocomplete(this.$refs.autocomplete)
        this.autocomplete.addListener('place_changed', this.update)
      })
    }
  }

И последнее, но не менее важное: метод update() получает место экземпляра автозаполнения и, если это реальное место (а не только текст), перемещает карту в это место и устанавливает там маркер:

update() {
  const place = this.autocomplete.getPlace()
  if (place.geometry) {
    this.map.panTo(place.geometry.location)
    this.markerPos = place.geometry.location
  }
}

Заключение

Это довольно простой пример, и я надеюсь добраться до более сложного, используя службу Google AutocompleteService, которая позволяет вам создавать свои собственные поля со списком. Более того, я хотел бы также включить готовые компоненты в пакет x5-gmaps ... Убедитесь, что вы дали мне несколько аплодисментов здесь и звезд на Github, чтобы я знал, что это того стоит. время 🧔