如何在Nuxt Js中使用Google Map API?

问题描述 投票:0回答:1

这是我在 Nuxt.Js 中获取 API 的代码。我已经编写了用于调用 API 的代码,但没有得到结果。我也没有得到任何与此相关的资源。

async created(){
  const config = {
    headers : {
      Accept : "application/json"
    }
  };
  try{
    const result = await axios.get(`https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap`, config);
    console.warn(result);
    //this.users = result.data;
  }
  catch (err){
    console.warn(err);
  }
},
vue.js nuxt.js
1个回答
5
投票

使用GM官方NPM加载器+diy Nuxt插件

Google Maps JS API 有一个官方的 npm 加载器:

https://developers.google.com/maps/documentation/javascript/overview#Loading_the_Maps_API

https://www.npmjs.com/package/@googlemaps/js-api-loader

下面是我如何在 Nuxt (2.15.7) 中实现它。

旁注: 是的,这会放置您的 API 密钥客户端,这在某些情况下(例如内部团队工具)很好。对于公共生产部署,您可能希望保护代理服务器后面的 API 密钥,并保持与 Google 的任何通信仅在您的服务器上进行。代理服务器非常适合 Google 搜索和地理定位服务等服务,但是对于地图图块,您可能永远不会拥有像 Google 一样快的地图图块服务器,因此您可能必须在客户端保留 API 密钥以确保平稳的性能。

1。安装

npm i @googlemaps/js-api-loader

2。制作你自己的 Nuxt 插件

plugins/mapGoogle.client.js

这使得 Google Map API 保持全局性,因此您可以在各种组件中使用它(即非地图上下文,例如在表单中搜索 Google Places)。

import Vue from 'vue'
import { Loader } from '@googlemaps/js-api-loader'

// Store GM_instance as a window object (outside of the Vue context) to satisfy the GM plugin.
window.GM_instance = new Loader({
    apiKey: process.env.GOOGLEMAPSAPIKEY, // This must be set in nuxt.config.js
    version: "weekly",
    libraries: ["places", "drawing", "geometry"] // Optional GM libraries to load
})

Vue.mixin({

    data() {
        return {
            GM_loaded: false, // Tracks whether already GM loaded
            GM_instance: null, // Holds the GM instance in the context of Vue; much more convenient to use *anywhere* (Vue templates or scripts) whereas directly accessing the window object within Vue can be problematic.
            GM_placeService: null, // Optional - Holds the GM Places service
        }
    },

    methods: {

        GM_load() {
            return new Promise( async (resolve, reject) => {

                // Need to do this only once
                if (!this.GM_loaded) {

                    // Load the GM instance
                    window.GM_instance.load()
                    .then((response) => {
                        this.GM_loaded = true
                        
                        // this.GM_instance is what we use to interact with GM throughout the Nuxt app
                        this.GM_instance = response

                        resolve()
                    })
                    .catch(e => {
                        reject(e)
                    })
                } else {
                    resolve()
                }
            })
        },

        // OPTIONAL FUNCTIONS:


        GM_loadPlaceService(map) {
            this.GM_placeService = new this.GM_instance.maps.places.PlacesService(map)
        },

        GM_getPlaceDetails(placeRequest) {
            return new Promise((resolve, reject) => {
                this.GM_placeService.getDetails(placeRequest, (response) => {
                    resolve(response)
                })
            })
        }
    }
})

3.在nuxt config中设置env和plugin

nuxt.config.js

从 .env 文件传递 GM 密钥并注册新插件。

export default {
    // ...

    // It's best to keep your GM key where all other keys are: your .env file; however this is inaccessible client-side.
    // Here, we tell Nuxt the specific env's we want to make available client-side.
    env: {
        GOOGLEMAPSAPIKEY: process.env.GOOGLEMAPSAPIKEY
    },

    // Register your new plugin
    plugins: [
        '@/plugins/mapGoogle.client.js',
    ],

    // ...
}

4。现在在任何地方都可以使用 GM 插件

components/map.vue

制作地图并处理 Google Places 上的点击

<template>
    <div id="map" class="map"></div>
</template>

<script>

export default {
    name: "MapGoogle",

    data() {
        return {
            map: null
        }
    },

    mounted() {

        // This is the actual trigger that loads GM dynamically.
        // Here we run our global GM func: GM_load.
        // Side note; annoyance: As you see, using Vue mixin's, you have functions available from out-of-nowhere. Research alternative to mixin's, especially in Vue3/Nuxt3.
        this.GM_load()
        .then( () => {
            this.initMap()
        })

    },


    methods: {

        initMap() {

            this.map = new this.GM_instance.maps.Map(document.getElementById("map"), {
                center: { lat: 43.682284, lng: -79.401603 },
                zoom: 8,
            })

            this.GM_loadPlaceService(this.map)

            this.map.addListener("click", (e) => {
                this.processClick(e)
            })

        }
    },

    async processClick(e) {
      
        // If clicked target has a placeId, user has clicked a GM place
        if (e.placeId) {
         
            let placeRequest = {
                placeId: e.placeId,
                //fields: ['name', 'rating', 'formatted_phone_number', 'geometry']
            }

            // Get place details
            let googlePlace = await this.GM_getPlaceDetails(placeRequest)
            console.log("googlePlace %O", googlePlace)
        }
            
    }
}
</script>
© www.soinside.com 2019 - 2024. All rights reserved.