完成イメージ
利用環境
"nuxt": "3.0.0-rc.11",
"vue": "^3.2.39"
前提条件
GoogleMapをウェブで利用する為にMaps JavaScript APIを利用します
APIキーの取得方法はこちらの記事参考ください。
導入方法
loaderをインストール
npm i @googlemaps/js-api-loader
@googlemaps/js-api-loader
は、Maps JavaScript API
を動的に読み込み、プロセスを Promise でラップします。 (JavaScript によって Maps JS API を読み込むことが可能となります)
読み込みオプションを利用して、ージョン、ライブラリ、apiKeyなどを指定することが可能になります。オプション参考
実装
templateには下記を追加します。
<template>
<div>
<div id="map" style="width: 100%; height: 600px;"></div>
<div>
<input
class="px-3 py-2 d-table-cell search-form-address"
v-model="searchText"
placeholder="Search Address"
style="display:block;"
>
<div>
<button
class="inline-flex p-2 hover:bg-gray-100 rounded"
@click="addressSearch"
>
検索
</button>
</div>
</div>
</div>
</template>
<script>
import { Loader } from '@googlemaps/js-api-loader';
export default {
data(){
return {
map: null,
google: null,
marker: null,
searchText: null,
}
},
mounted(){
new Loader({
// 取得したAPIキーを入力
apiKey: '********************************',
// 動作が安定したバージョン。この段階のバージョンは、バグ修正で変更されることはある。
version: 'Release',
// 追加のライブラリを読み込む場合はライブラリ(複数可)の名前を指定
// 参照:https://developers.google.com/maps/documentation/javascript/libraries?hl=ja
libraries: ["places", "drawing", "geometry", "visualization"],
language: 'ja',
})
.load()
.then((google) => {
this.google = google;
// 地図の初期化
this.map = new google.maps.Map(document.getElementById('map'), {
// コントロールの概要設定
zoom : 17, // 初期表示設定
center: { lat: 35.692195, lng: 139.759854 }, // マルティスープ本社
fullscreenControl: false, // 全画面モードで地図を開くコントロールを無効
mapTypeControl: false, // 地図タイプ(地図や航空写真など)を切り替える地図タイプのコントロールを無効
streetViewControl: true, // ユーザーがストリートビュー パノラマの有効
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
zoomControl: true, // ズーム コントロールの有効
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM
},
scaleControl: true, // 簡単な地図の縮尺調整機能を表示するスケール コントロールを有効
});
})
.catch(e => {
console.error(e);
});
},
methods: {
addressSearch () {
const vm = this;
const geocoder = new this.google.maps.Geocoder();
if (geocoder) {
// コールバックでは、results と status のコードをこの順序で保持する 2 つのパラメータを渡す必要がある
geocoder.geocode({address: this.searchText }, function(results, status) {
if(vm.marker){
// Maps JavaScript APIの公式ドキュメントによるとMarker.setMap(null)で削除できるらしい.. がObjectの関連は消えるが地図上からは消えなかった。。
// 事前にMarker.setVisible(false)することで解決(trueなら表示状態、falseなら非表示状態になる。)
vm.marker.setVisible(false);
vm.marker.setMap(null);
vm.marker = null;
}
if (status === vm.google.maps.GeocoderStatus.OK) {
// マーカーの設定
vm.marker = new vm.google.maps.Marker({
map: vm.map,
position: results[0].geometry.location,
draggable: false,
});
// 地図の位置座標をセットすると同時に、表示もその位置に変更する
vm.map.setCenter(results[0].geometry.location);
}
});
}
}
}
}
</script>
ハマりポイント
InvalidValueError: initMap is not a functionの対応
message: "Map: Expected mapDiv of type HTMLElement but was passed null."
name: "InvalidValueError"
ページを読み込んだ際に発生するエラー
原因:Google Maps のスクリプトを非同期で読み込んでいるため、
mountedを宣言したときに存在していない場合がある?
対策:読み込みタイミングをずらす
例)
window.onload = function () {
処置内容
}
参考リンク
公式ガイド:https://developers.google.com/maps/documentation/javascript