Google Maps利用するだけやしすぐ終わるやろと思っていましたが、少しはまってしまいました。
当たり前ですが、この手のものは利用時に最新情報拾っていくのが良いです。
(ここも含めて)その辺のブログを鵜呑みにせず、必ず公式見ましょう。
xkjyeah/vue-google-maps
Installation
リポジトリ名と若干違ってややこしいのですが、 nuxtで利用できるvu2用のnpmは、 vue2-google-maps
です。
これをnpm/yarnで入れるだけ。
Nuxt用設定
vue用として作られていますが、ご親切にnuxt用のQuickstartが記載されています。
基本はこの通りにやるだけです。
Quickstart (Webpack, Nuxt):
nuxt.config.js
公式とは順不同ですが、config設定してから開発入る方が、普通の流れなのでこちらから。
// nuxt.config.js build: { transpile: [/^vue2-google-maps($|\/)/] },
これだけで良いです。
build.extend()
に書けと記載されていますが、今はtranspileに設定するだけで良いです。(PR出しておきました。)
VueGoogleMapsの設定
In your main.js or inside a Nuxt plugin:
と記載がありますが、pluginに書く方が好みなので、そちらで。
// plugins/vue2-google-maps.js import Vue from 'vue' import * as VueGoogleMaps from '~/node_modules/vue2-google-maps' Vue.use(VueGoogleMaps, { load: { key: process.env.YOUR_GOOGLE_API_KEY, libraries: 'places', }, })
基本設定はこれだけですが、地名のautocomplete用の設定などもあるようです。
plugins以下に書いたので、configに設定を追加します。
// nuxt.config.js plugins: [ { src: '~/plugins/vue2-google-maps.js' } ],
GmapMapで描画
基本はこんな感じ。
<GmapMap :center="{lat:10, lng:10}" :zoom="7" map-type-id="terrain" style="width: 500px; height: 300px" > <GmapMarker :key="index" v-for="(m, index) in markers" :position="m.position" :clickable="true" :draggable="true" @click="center=m.position" /> </GmapMap>
応用編
Reference
localでbuildしてから気づいたんだけど、exapmles/autoapi.html が用意されていてbuildするとapi documentが生成されます。
んでもって、以下にhostingされています。
http://xkjyeah.github.io/vue-google-maps/autoapi.html
Gmapオブジェクト
ref属性を指定しておけば、jsで扱えます。
<GmapMap
ref="gmap"
this.$refs.gmap
InfoWindow
Markerクリック時に吹き出しを表示するのに使えます。 Markerの子要素としても作れるみたいですが、クリック時に表示させるのは1つで良いので、今回は以下の様に実装。
<GmapMarker :key="index" v-for="(shop, index) in shops" :position='{ "lat": shop.lat, "lng": shop.lng }' :clickable="true" :draggable="false" @click="toggleInfoWindow(shop)" /> <GmapInfoWindow :options="map.infoWindow.options" :position="map.infoWindow.position" :opened="map.infoWindow.shown" @closeclick="map.infoWindow.shown=false" >
あとは、toggleInfoWindow で表示制御をするだけ。
fitBounds
Google MapsのAPIには、複数Markerがある場合に、拡大率をいい感じに自動で設定してくれるfitBoundsというオプションがあるんだけど、これの使い方が分からず、結構ハマりました。
Maps JavaScript API | Google Developers
https://github.com/xkjyeah/vue-google-maps/blob/8d6bbac96b0797cf1e5b9537d58920c23ba75bd2/examples/components/02LatLngBounds.vue#L35
ここにexampleがあり、求めていたのこれこれと思って利用するも、動作せず。
どうも非同期読み込みのせいっぽい。
しばらくexampleを眺めている、 $gmapApiPromiseLazy()
というそれっぽいやつがあることに気づきました。
https://github.com/xkjyeah/vue-google-maps/blob/8d6bbac96b0797cf1e5b9537d58920c23ba75bd2/src/components-implementation/autocomplete.js#L47
githubを検索すると、wikiがhit。
https://github.com/xkjyeah/vue-google-maps/wiki/vue-google-maps-FAQ#where-is-my-google
ということで、exampleに $gmapApiPromiseLazy()
を利用する形で解決。
watch: { shops(shops) { this.$gmapApiPromiseLazy().then(() => { if (shops.length > 2) { const bounds = new google.maps.LatLngBounds() for (let shop of shops) { bounds.extend({ "lat": shop.lat, "lng": shop.lng }) } this.$refs.gmap.fitBounds(bounds) } }) } },