Нам нужно получить ключ API Javascript здесь: https://developers.google.com/maps/documentation/javascript/get-api-key. Это отличается от ключа API на стороне сервера, который мы получили при настройке геокодирование.

После того, как вы нажмете Get A Key, как показано ниже, вы можете выбрать свой проект или создать новый проект, и появится ключ.

Шаг 2. Добавьте ключ JS API в файл config.js.

Подобно переменным среды, которые мы настроили в Laravel с помощью API геокодирования, мы должны хранить этот ключ в месте, которое можно использовать повторно. Это открытый ключ, вы можете сохранить его в своем JS-файле.

Ваш файл /resources/assets/js/config.js должен выглядеть так:

/*
    Defines the API route we are using.
*/
var api_url = '';
var google_maps_js_api = '{YOUR_KEY_HERE}';

switch( process.env.NODE_ENV ){
  case 'development':
    api_url = 'https://roast.dev/api/v1';
  break;
  case 'production':
    api_url = 'https://roastandbrew.coffee/api/v1';
  break;
}

export const ROAST_CONFIG = {
  API_URL: api_url,
  GOOGLE_MAPS_JS_API: google_maps_js_api
}

Шаг 3. Настройте безопасность вашего ключа

Убедитесь, что вы также настроили надлежащую безопасность, чтобы ваша квота не была украдена. Для этого зайдите в консоль разработчиков Google: Google Cloud Platform и выберите свой проект. На панели инструментов вы увидите все API, которые вы включили для своего проекта.

Щелкните вкладку учетных данных в левой части экрана:

Вы должны увидеть 2 ключа API и клиент Web oAuth, если вы следовали серии руководств. Если нет, вы должны увидеть только что созданный ключ API. Нажмите маленькую ссылку редактирования справа от списка:

Вы попадете на страницу, где сможете отредактировать всю информацию для своего ключа API. Я даю ему имя, чтобы его было легче распознать, но в целях безопасности вы должны ограничить рефереры HTTP (веб-сайты) и в раскрывающемся списке ввести свои домены, на которых вы хотите использовать ключи. В этом случае я использую ключ наropeandbrew.coffee иrope.dev для своей разработки.

Обратите внимание на * после URL-адресов? Это позволяет разместить карту на любой странице. При необходимости вы также можете ограничиться определенными страницами.

Теперь ваш API-ключ будет проверяться только тогда, когда он исходит из вашего домена. Нажмите «Сохранить», и все готово!

Шаг 4: Добавьте скрипт Google Maps в app.blade.php

Чтобы убедиться, что скрипт Google Maps добавлен в ваше приложение, откройте файл resources/views/app.blade.php и добавьте следующую строку кода в теги head:

<script async defer src="https://maps.googleapis.com/maps/api/js?key={YOUR_GOOGLE_MAPS_API_KEY}"></script>

Введите соответствующий API-ключ для звонка! Это асинхронная загрузка скрипта. Если вы делаете это вне VueJS, вы можете добавить обратный вызов, который вызывается при успешной загрузке скрипта. Мы будем загружать карту внутри компонента, когда страница будет готова, поэтому мы будем делать это немного по-другому.

Шаг 5: Добавьте компонент CafeMap

Мы будем хранить нашу карту как компонент, который мы можем вставить на нашу страницу Cafes. Это разделит функциональные проблемы и упростит обновление данных, которые нам нужны.

Сначала мы добавим следующую папку: /resources/assets/js/components/cafes/. В этот каталог добавьте файл с именем CafeMap.vue. Это будет наш компонент карты.

В файле CafeMap.vue добавьте заглушенную структуру компонента Vue следующим образом:

<style lang="scss">

</style>

<template>
  <div id="cafe-map">

  </div>
</template>

<script>
  export default {

  }
</script>

Шаг 6: Добавьте карту Google

А вот что касается Google Map, это переменная, но мы НЕ хотим, чтобы Vue применял свое реактивное наблюдение ко всем методам, ему это не нужно. Поэтому мы сделаем трюк, чтобы определить его локально за пределами нашего объекта данных. Другой трюк заключается в том, что нам нужно, чтобы HTML-код отображался компонентом, прежде чем мы сможем построить карту. Каждая карта Google нуждается в предопределенных ширине и высоте. Это означает, что нам нужно взглянуть на хуки жизненного цикла, предоставляемые VueJS. Лучше всего работает хук mounted().

Сначала нам нужно добавить к нашему компоненту хук mounted() следующим образом:

<style lang="scss">

</style>

<template>
  <div id="cafe-map">

  </div>
</template>

<script>
  export default {
    mounted(){

        }
  }
</script>

Далее нам нужно будет добавить к карте ширину и высоту по умолчанию, поэтому в нашем scss добавьте:

<style lang="scss">
  div#cafe-map{
    width: 100%;
    height: 400px;
  }
</style>

Теперь последнее, что нам нужно сделать, это добавить несколько свойств для широты и долготы по умолчанию, необходимых для карты. Я добавил их как свойства, чтобы мы могли изменить их при необходимости при инициализации карты. Наш компонент CafeMap должен выглядеть так:

<style lang="scss">
  div#cafe-map{
    width: 100%;
    height: 400px;
  }
</style>

<template>
  <div id="cafe-map">

  </div>
</template>

<script>
  export default {
    props: {
      'latitude': {
        type: Number,
        default: function(){
          return 39.50
        }
      },
      'longitude': {
        type: Number,
        default: function(){
          return -98.35
        }
      },
      'zoom': {
        type: Number,
        default: function(){
          return 4
        }
      }
    },

    data(){
      return {

      }
    },

    mounted(){

    }
  }
</script>

Как видите, я предоставил некоторые значения по умолчанию и типы для свойств. VueJS позволяет пользователю определить, какого типа должно быть каждое свойство, поэтому при создании повторно используемого компонента разработчик не получает неверные данные, передаваемые компоненту. Полный список типов проверки можно найти в документации Vue здесь: Компоненты — Vue.js.

Я также добавил уровень масштабирования в свойства, чтобы разработчик мог добавить желаемое масштабирование карты.

Теперь у нас достаточно данных, и мы можем, наконец, инициализировать нашу карту. Как мы упоминали ранее, мы не хотим, чтобы карта была реактивной, поэтому мы не будем определять ее в нашем методе data(), но мы хотим, чтобы она была ограничена и на нее ссылались внутри нашего компонента. Итак, в наш хук жизненного цикла mounted() добавьте следующее:

mounted(){
      /*
        We don't want the map to be reactive, so we initialize it locally,
        but don't store it in our data array.
      */
      this.map = new google.maps.Map(document.getElementById('cafe-map'), {
        center: {lat: this.latitude, lng: this.longitude},
        zoom: this.zoom
      });
    }

Когда мы используем this.map, мы присваиваем карту локальной переменной, которую можем использовать внутри области действия нашего компонента. Мы также инициализируем карту, чтобы она представляла собой широту и долготу передаваемых свойств, а также уровень масштабирования по умолчанию.

Теперь у нас есть наша карта, готовая к рок-н-роллу, еще несколько шагов, и мы можем отобразить наши кафе!

Шаг 7. Добавьте компонент CafeMap.vue на страницу кафе.

Мы хотим отобразить карту на странице кафе. Сначала мы откроем страницу /resrouces/assets/js/pages/Cafes.vue.

Теперь, прежде чем мы экспортируем наш модуль по умолчанию, нам нужно импортировать наш компонент CafeMap.

Добавьте импорт над экспортом по умолчанию:

import CafeMap from '../components/cafes/CafeMap.vue';

Теперь нам нужно сообщить нашей странице Cafes, что мы будем использовать компонент CafeMap, определив его в компонентах следующим образом:

export default {
  components: {
    CafeMap
  }
}

И последнее, но не менее важное: нам нужно добавить компонент на страницу, чтобы наша обновленная страница кафе выглядела так:

<style>

</style>

<template>
  <div id="cafes">
    <div class="grid-x">
      <div class="large-9 medium-9 small-12 cell">
        <cafe-map></cafe-map>
      </div>
      <div class="large-3 medium-3 small-12 cell">

      </div>
    </div>
  </div>
</template>

<script>
  import CafeMap from '../components/cafes/CafeMap.vue';

  export default {
    components: {
      CafeMap
    }
  }
</script>

Если вы посетите страницу, вы должны увидеть красивую карту Google, ожидающую вас вот так:

Шаг 8: Добавление кафе на карту

Это последний шаг в руководстве. Нам нужно, чтобы наши кафе, которые мы загрузили, были добавлены на карту. Для этого мы добавим кафе в качестве маркеров. Прямо сейчас маркеры будут просто заполнителями, в следующих уроках мы настроим маркеры, настроим информационные окна, маркеры фильтров и т. д.

Сначала нам нужно добавить массив маркеров к нашим данным в компоненте CafeMap.vue следующим образом:

data(){
  return {
    markers: []
  }
},

Это будет массив, в котором мы будем хранить все наши маркеры.

Теперь нам нужно импортировать все загруженные нами кафе. Это хранится в нашем модуле Vuex (Сборка модуля Vuex — на стороне сервера), который загружается в наш макет из нашего макета (https://serversideup.net/building-page-layout-vue-router/).

Чтобы добавить наш Vuex на страницу Cafes, нам нужно загрузить данные из Vuex как вычисляемое свойство:

computed: {
  /*
    Gets the cafes
  */
  cafes(){
    return this.$store.getters.getCafes;
  }
},

Теперь мы можем ссылаться на кафе со страницы «Кафе». Далее нам нужно добавить несколько методов.

Первый метод — это метод buildMarkers(). Что это сделает, так это создаст маркер Google Maps Маркеры | API JavaScript Карт Google | Google Developers для каждого из наших Кафе. Итак, добавьте объект methods и метод buildMarkers():

methods: {
  buildMarkers(){

  }
}

В этом методе мы перебираем все загруженные нами кафе, создаем маркер Google Maps и устанавливаем его на карту, которую мы определили. Затем мы добавим маркер в массив маркеров в данных. Наш метод должен выглядеть так:

/*
  Builds all of the markers for the cafes
*/
buildMarkers(){
  /*
    Initialize the markers to an empty array.
  */
  this.markers = [];

  /*
    Iterate over all of the cafes
  */
  for( var i = 0; i < this.cafes.length; i++ ){

    /*
      Create the marker for each of the cafes and set the
      latitude and longitude to the latitude and longitude
      of the cafe. Also set the map to be the local map.
    */
    var marker = new google.maps.Marker({
      position: { lat: parseFloat( this.cafes[i].latitude ), lng: parseFloat( this.cafes[i].longitude ) },
      map: this.map
    });

    /*
      Push the new marker on to the array.
    */
    this.markers.push( marker );
  }
}

Что это делает, так это инициализирует маркеры пустым массивом. Это так, если кафе будет добавлено, мы можем добавить его в новый массив. Затем мы перебираем все кафе в модуле Vuex. Для каждого кафе мы создаем маркер Google Maps и устанавливаем широту и долготу в соответствии с широтой и долготой кафе. Мы также устанавливаем карту на нашу карту Google. Затем мы помещаем маркер в массив markers.

Теперь, когда у нас построены маркеры, мы должны написать метод clearMarkers(). Это удалит маркеры с карты. Это полезно, когда мы повторно отображаем страницу, загружаем новое кафе и т. д. Этот метод очень прост, он просто устанавливает для каждого маркера на карте нашего массива значение null, используя метод setMap(), доступный для каждого маркера. Метод очистки маркеров должен выглядеть так:

/*
  Clears the markers from the map.
*/
clearMarkers(){
  /*
    Iterate over all of the markers and set the map
    to null so they disappear.
  */
  for( var i = 0; i < this.markers.length; i++ ){
    this.markers[i].setMap( null );
  }
},

Теперь нам нужно связать их вместе. В конце метода mounted() мы должны очистить и перестроить маркеры. Что это сделает, так это очистит все старые маркеры, прежде чем мы сбросим массив маркеров, и построим его с кафе. Добавьте следующие строки в конец метода mounted():

/*
  Clear and re-build the markers
*/
this.clearMarkers();
this.buildMarkers();

Наконец, нам нужно добавить наблюдателя к нашему cafes. Когда кафе будут обновлены, нам нужно очистить маркеры и перестроить их. Для получения дополнительной информации о наблюдателях ознакомьтесь с: Вычисляемые свойства и наблюдатели — Vue.js. Для этого добавьте наблюдателя в компонент CafeMap.vue следующим образом:

watch: {
    cafes(){

    }
},

Это будет следить за вычисляемым свойством cafes и, когда оно изменится, запустить метод. В данном случае мы хотим очистить и перестроить маркеры, поэтому добавляем те же две строчки кода:

watch: {
  /*
    Watches the cafes. When they are updated, clear the markers
    and re build them.
  */
  cafes(){
    this.clearMarkers();
    this.buildMarkers();
  }
},

Теперь у нас есть настроенный компонент, поэтому, когда кафе меняются, мы перестраиваем маркеры, а когда компонент монтируется, мы перестраиваем маркеры. Таким образом, если кафе будет добавлено, оно будет прямо на нашей карте, и если мы уйдем со страницы кафе и вернемся назад, у нас все еще будут наши маркеры. Если вы посетите маршрут /cafes/, вы должны увидеть добавленные маркеры кафе:

Наш компонент CafeMap.vue должен выглядеть так:

<style lang="scss">
  div#cafe-map{
    width: 100%;
    height: 400px;
  }
</style>

<template>
  <div id="cafe-map">

  </div>
</template>

<script>
  export default {
    props: {
      'latitude': {
        type: Number,
        default: function(){
          return 39.50
        }
      },
      'longitude': {
        type: Number,
        default: function(){
          return -98.35
        }
      },
      'zoom': {
        type: Number,
        default: function(){
          return 4
        }
      }
    },

    data(){
      return {
        markers: []
      }
    },

    computed: {
      /*
        Gets the cafes
      */
      cafes(){
        return this.$store.getters.getCafes;
      }
    },

    watch: {
      /*
        Watches the cafes. When they are updated, clear the markers
        and re build them.
      */
      cafes(){
        this.clearMarkers();
        this.buildMarkers();
      }
    },

    mounted(){
      /*
        We don't want the map to be reactive, so we initialize it locally,
        but don't store it in our data array.
      */
      this.map = new google.maps.Map(document.getElementById('cafe-map'), {
        center: {lat: this.latitude, lng: this.longitude},
        zoom: this.zoom
      });

      /*
        Clear and re-build the markers
      */
      this.clearMarkers();
      this.buildMarkers();
    },

    methods: {
      /*
        Clears the markers from the map.
      */
      clearMarkers(){
        /*
          Iterate over all of the markers and set the map
          to null so they disappear.
        */
        for( var i = 0; i < this.markers.length; i++ ){
          this.markers[i].setMap( null );
        }
      },

      /*
        Builds all of the markers for the cafes
      */
      buildMarkers(){
        /*
          Initialize the markers to an empty array.
        */
        this.markers = [];

        /*
          Iterate over all of the cafes
        */
        for( var i = 0; i < this.cafes.length; i++ ){

          /*
            Create the marker for each of the cafes and set the
            latitude and longitude to the latitude and longitude
            of the cafe. Also set the map to be the local map.
          */
          var marker = new google.maps.Marker({
            position: { lat: parseFloat( this.cafes[i].latitude ), lng: parseFloat( this.cafes[i].longitude ) },
            map: this.map
          });

          /*
            Push the new marker on to the array.
          */
          this.markers.push( marker );
        }
      }
    }
  }
</script>

Вывод

Карты Google чрезвычайно мощны и имеют отличную документацию. В будущих руководствах мы будем настраивать внешний вид карты. А пока не стесняйтесь проверять весь исходный код здесь: GitHub — serversideup/roastandbrew.

Привет! Мы пишем книгу по разработке приложений на основе API. Узнай первым, как только он будет готов! Зарегистрируйтесь здесь: Регистрация для разработки приложений на основе API