nuxt.js & vue2-google-maps

# 概要 
- 【目的】nuxt.jsでGoogleMapを使いたい
- 前提
    - GoogleMap APIを取得済み
- vue2-google-maps 関連サイト
    - https://www.npmjs.com/package/vue2-google-maps
    - https://github.com/xkjyeah/vue-google-maps 
    - https://www.youtube.com/watch?v=2QboO0zuZ2Q 
- 環境
    - Windows10
    - VSCode
    - Node v8.11.3
   
# sample Project作成
make nuxt project

```
> npx create-nuxt-app sample_googlemaps
? Project name sample_googlemaps
? Project description My luminous Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework vuetify
? Choose rendering mode Universal
? Use axios module yes
? Use eslint no
? Author name testuser
? Choose a package manager npm
```

 install vue2-google-maps

```
>  npm i vue2-google-maps --save
```

#Nuxt.js configの修正
Plugin読み込み設定

```js:nuxt.config.js
  plugins: [
    '@/plugins/vuetify',
    {src:"~plugins/vue2-google-maps.js"} // 追加
  ],
```
build.extend()に下記を追記

```js:nuxt.config.js
  build: {
    /*
    ** You can extend webpack config here
    */
    extend(config, ctx) {
       -- 略 --

      //add for vue2-google-maps
      if (!ctx.isClient) {
        // This instructs Webpack to include `vue2-google-maps`'s Vue files
        // for server-side rendering
        config.externals.splice(0, 0, function (context, request, callback) {
          if (/^vue2-google-maps($|\/)/.test(request)) {
            callback(null, false)
          } else {
            callback()
          }
        })
      }
```
venderへの追加

```js:nuxt.config.js
    vendor:["vue2-google-maps"]
  },
}
```

#pluginの追加
pulugin フォルダにvue2-google-maps.jsを作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/158724/10bcb845-1f39-5001-f3d6-7db8c70e3ecb.png)

```js:vue2-google-maps.js
import Vue from 'vue'
import * as VueGoogleMaps from 'vue2-google-maps'
 
Vue.use(VueGoogleMaps, {
  load: {
    key: '{GoogleMapのAPIキー}',
    libraries: 'places', 
  },
})
```

# 画面(Vue)作成
最小限のLayout

```html:layouts/default.vue
<template>
  <v-app dark>  
      <nuxt />
  </v-app>
</template>
```

GoogleMapを表示する画面

```html:page/index.vue
<template>
<v-layout row justify-center align-center>

<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>

</v-layout>
</template>

<script>
export default {
  data() {
    return {
      markers: [
        {position: { lng: 10.2, lat: 10 }},
        {position: { lng: 10.1, lat: 10 }}
      ]
    };
  }
};
</script>
```

# サンプル実行結果
>npm run dev

![image.png](https://qiita-image-store.s3.amazonaws.com/0/158724/e05df0dd-c4d1-01af-3d4f-96325fa16a59.png)

# 現在地の取得
navigator.geolocation.getCurrentPositionを使う
参考：https://syncer.jp/how-to-use-geolocation-api 

```html:current.vue
<template>
<div>
    <v-btn @click="onClickCurrent" >getCurrentPosition</v-btn>
    <p>{{currentLoc.coords}}</p>

    <GmapMap class="map-panel" map-type-id="terrain" 
        style="width: 100%; height: 300px"
        :draggable="true"
        :center="maplocation"
        :zoom="15"
        ref="mmm">
        <GmapMarker 
        :position = "maplocation" 
        />

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

<script>
export default {
    data(){
        return {
            currentLoc:{},
            maplocation:{lng: 0, lat: 0}
        }
    },
    methods:{
        async onClickCurrent(){
            console.log('--onClickCurrent')
            try{
                
                let data =await getPosition();
                console.log('--success',data)
                console.log('typeof', typeof(data))
                
                let data2={};
                data2.lat = data.coords.latitude ;
                data2.lng = data.coords.longitude ;
                data2.alt = data.coords.altitude ;
                data2.accLatlng = data.coords.accuracy ;
                data2.accAlt = data.coords.altitudeAccuracy ;
                data2.heading = data.coords.heading ;			//0=北,90=東,180=南,270=西
                data2.speed = data.coords.speed ;

                // Object.assign(data2,data.coords); // not work
                // this.$set(this.currentLoc,"data2",data.coords);//not work
                console.log('data2',data2)
                this.$set(this.currentLoc,"coords",data2);

                //set Googlemap
                this.maplocation.lat = data2.lat;
                this.maplocation.lng = data2.lng;
                this.$refs.mmm.panTo(this.maplocation );
                
            }catch(e){
                console.log('--error',e);
            }
        }
    },
}
var getPosition = function (options) {
  return new Promise(function (resolve, reject) {
    navigator.geolocation.getCurrentPosition(resolve, reject, options);
  });
}
</script>
```

実行結果省略

# （追記）Nuxt upgrade 1.4 -> 2.2 対応

参考
  - https://codesandbox.io/s/31j9l75xjm
  
## upgrade
> \>yarn upgrade-interactive --latest

nuxtをチェックしてアップグレードを行う

## add core-js package

> \>yarn add core-js

## fix code (nuxtconfg.js)


```javascript:nuxt.config.js

  plugins: [{ src: "~/plugins/vue2-google-maps", ssr: true }],
  build: {
    transpile: [/^vue2-google-maps($|\/)/]
  }

```