这是我在 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);
}
},
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 密钥以确保平稳的性能。
npm i @googlemaps/js-api-loader
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)
})
})
}
}
})
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',
],
// ...
}
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>