Vue.js+TypeScriptでGoogleMapを使う
Vue.js公式のcookbookにexampleが乗ってる
- https://jp.vuejs.org/v2/cookbook/practical-use-of-scoped-slots.html
- slotを使ってGoogle Mapをロードする用のコンポーネントを作成
- scoped slotでgoogle, map propertyを公開する
- 親コンポーネントで、slotのpropertyを使ってmarkerやpolylineを描画するのに使う
- markerコンポーネントを作ってpropsにgoogleやmapを渡すことで使うことができる
TypeScript
https://developers.google.com/maps/documentation/javascript/using-typescript
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/googlemaps/ DefinitelyTypedにあるものを使う
Vue.js
- https://jp.vuejs.org/v2/cookbook/practical-use-of-scoped-slots.html に則って実装
- @googlemaps/js-api-loader でロード
- @types/googlemaps で型付け
GoogleMapLoader.vue
GoogleMapMarker.vue
困ったこと
@types/googlemaps
の定義がnamespaceになっているのでそのままだとgoogle型が使えない
declare namespace google.maps {
...
}
解決策
typeof google
で型宣言する
// eslint-disable-next-line no-undef
let google: typeof google | null = null
VeturでNull-safety operatorが怒られる(バグ?)
initializeMap() {
const mapContainer = this.$refs.googleMap
this.map = new this.google?.maps.Map(mapContainer, this.mapConfig)
}
This expression is not constructable.
Type 'typeof google' has no construct signatures.Vetur(2351)
解決策
あらかじめnull判定をしておく
initializeMap() {
const mapContainer = this.$refs.googleMap
if (!this.google) {
return
}
this.map = new this.google.maps.Map(mapContainer, this.mapConfig)
}
その他ドキュメント
https://developers.google.com/maps/documentation/javascript/examples/event-simple