谷歌地图 允许您将地图嵌入到您的网站中,并使用您的内容进行自定义。
Nuxt 脚本提供了一个 useScriptGoogleMaps
可组合组件和一个无头 ScriptGoogleMaps
组件来与谷歌地图交互。
ScriptGoogleMaps
The ScriptGoogleMaps
组件是 useScriptGoogleMaps
可组合组件的包装器。它提供了一种简单的方法,可以将谷歌地图嵌入到您的 Nuxt 应用程序中。
它通过利用 元素事件触发器 进行了性能优化,只在特定元素事件发生时加载谷歌地图。
在加载谷歌地图之前,它使用 静态地图 API 显示一个占位符。
默认情况下,它将在 mouseover
和 mouseclick
事件上加载。
计费和权限
显示交互式 JS 地图需要地图 JavaScript API,这是一个付费服务。如果用户与地图交互,将产生以下费用
- 地图 JavaScript API 每 1000 次加载收取 7 美元(使用谷歌地图的默认值)
- 静态地图 API 每 1000 次加载收取 2 美元 - 仅在您不提供
placeholder
插槽时使用。 - 地理编码 API 每 1000 次加载收取 5 美元 - 仅在您不提供
google.maps.LatLng
对象(而不是center
属性的查询字符串)时使用。
但是,如果用户从未与地图交互,则仅会收取静态地图 API 使用费(每 1000 次加载 2 美元),假设您正在使用它。
计费将在 未来的更新 中优化。
如果您想避免这些费用并且可以接受交互性较低的地图,则应该考虑使用 Iframe 嵌入。
演示
静态图像:悬停以加载交互式
属性
The ScriptGoogleMaps
组件接受以下属性。
您必须提供一个 center
属性才能使地图正确加载,或者您应该提供 mapOptions
并在其中配置 center
选项。
地图
center
: 地图的中心位置。您可以提供一个包含位置的字符串,或使用{ lat: 0, lng: 0 }
对象。apiKey
: 谷歌地图 API 密钥。必须具有访问静态地图 API 的权限。您也可以选择使用public.scripts.googleMaps.apiKey
密钥将其作为运行时配置提供。centerMarker
: 是否在中心位置显示标记。默认为true
。mapOptions
: 地图的选项。请参阅 地图选项。
占位符
您可以使用以下属性自定义占位符图像,或者您可以使用 #placeholder
插槽自定义占位符图像。
placeholderOptions
: 自定义占位符图像属性。请参阅 静态地图 API。placeholderAttrs
: 自定义占位符图像属性。
大小
如果您想渲染一个大于 640x640 的地图,您应该提供自己的占位符,因为 静态地图 API 不支持渲染大于此尺寸的地图。
width
: 地图的宽度。默认为640
。height
: 地图的高度。默认为400
。
优化
trigger
: 加载谷歌地图的触发事件。默认为mouseover
。请参阅 元素事件触发器 以了解更多信息。aboveTheFold
: 为屏幕上可见内容优化占位符图像。默认为false
。
标记
您可以通过提供一个 MarkerOptions
数组来向静态地图和交互式地图添加标记。请参阅 标记选项。
markers
: 要在地图上显示的标记数组。
有关更多信息,请参阅 标记 示例。
指南
立即加载占位符
谷歌地图占位符图像默认情况下是延迟加载的。如果您地图在屏幕上可见内容区域,则应该更改此行为,或者考虑使用 #placeholder
插槽自定义占位符图像。
<ScriptGoogleMaps above-the-fold />
高级标记控制
如果您需要对地图上的标记进行更多控制,可以使用公开的 createAdvancedMapMarker
函数,该函数将返回标记实例。
<script lang="ts" setup>
const googleMapsRef = ref()
onMounted(() => {
const marker = googleMapsRef.value.createAdvancedMapMarker({
position: { }
})
})
</script>
<template>
<ScriptGoogleMaps ref="googleMapsRef" />
</template>
高级地图控制
该组件公开了所有内部 API,因此您可以根据需要自定义地图。
<script lang="ts" setup>
const googleMapsRef = ref()
onMounted(async () => {
const api = googleMapsRef.value
// Access internal APIs
const googleMaps = api.googleMaps.value // google.maps api
const mapInstance = api.map.value // google.maps.Map instance
// Convert a query to lat/lng
const query = await api.resolveQueryToLatLang('Space Needle, Seattle, WA') // { lat: 0, lng: 0 }
// Import a Google Maps library
const geometry = await api.importLibrary('geometry')
const distance = new googleMaps.geometry.spherical.computeDistanceBetween(
new googleMaps.LatLng(0, 0),
new googleMaps.LatLng(0, 0)
)
})
</script>
<template>
<ScriptGoogleMaps ref="googleMapsRef" />
</template>
立即加载
如果您想立即加载谷歌地图,可以使用 trigger
属性。
<template>
<ScriptGoogleMaps trigger="immediate">
</ScriptGoogleMaps>
</template>
地图样式
您可以使用 mapOptions.styles
属性来设置地图的样式。您可以在 Snazzy 地图 上找到预制样式。
这将自动适用于静态地图占位符和交互式地图。
<script setup lang="ts">
const mapOptions = {
styles: [{ elementType: 'labels', stylers: [{ visibility: 'off' }, { color: '#f49f53' }] }, { featureType: 'landscape', stylers: [{ color: '#f9ddc5' }, { lightness: -7 }] }, { featureType: 'road', stylers: [{ color: '#813033' }, { lightness: 43 }] }, { featureType: 'poi.business', stylers: [{ color: '#645c20' }, { lightness: 38 }] }, { featureType: 'water', stylers: [{ color: '#1994bf' }, { saturation: -69 }, { gamma: 0.99 }, { lightness: 43 }] }, { featureType: 'road.local', elementType: 'geometry.fill', stylers: [{ color: '#f19f53' }, { weight: 1.3 }, { visibility: 'on' }, { lightness: 16 }] }, { featureType: 'poi.business' }, { featureType: 'poi.park', stylers: [{ color: '#645c20' }, { lightness: 39 }] }, { featureType: 'poi.school', stylers: [{ color: '#a95521' }, { lightness: 35 }] }, {}, { featureType: 'poi.medical', elementType: 'geometry.fill', stylers: [{ color: '#813033' }, { lightness: 38 }, { visibility: 'off' }] },
}
</script>
<template>
<ScriptGoogleMaps :mapOptions="mapOptions" />
</template>
组件 API
请参阅 外观组件 API 以了解完整的属性、事件和插槽。
事件
The ScriptGoogleMaps
组件在谷歌地图加载时发出一个 ready
事件。
const emits = defineEmits<{
ready: [map: google.maps.Map]
}>()
要订阅谷歌地图事件,可以使用 ready
事件。
<script setup lang="ts">
function handleReady({ map }) {
map.addListener('center_changed', () => {
console.log('Center changed', map.getCenter())
})
}
</script>
<template>
<ScriptGoogleMaps @ready="handleReady" />
</template>
插槽
该组件默认情况下提供最少的 UI,仅足以使其功能齐全且可访问。您可以通过多种插槽以您喜欢的方式自定义地图。
default
default 插槽用于显示始终可见的内容。
<template>
<ScriptGoogleMaps>
<div class="absolute top-0 left-0 right-0 p-5 bg-white text-black">
<h1 class="text-xl font-bold">
My Custom Map
</h1>
</div>
</ScriptGoogleMaps>
</template>
awaitingLoad
该插槽用于在加载谷歌地图时显示内容。
<template>
<ScriptGoogleMaps>
<template #awaitingLoad>
<div class="bg-blue-500 text-white p-5">
Click to load the map!
</div>
</template>
</ScriptGoogleMaps>
</template>
loading
该插槽用于在加载谷歌地图时显示内容。
注意:这默认情况下显示一个 ScriptLoadingIndicator
以实现可访问性和用户体验,通过提供一个插槽,您将覆盖此组件。确保您提供了一个加载指示器。
<template>
<ScriptGoogleMaps>
<template #loading>
<div class="bg-blue-500 text-white p-5">
Loading...
</div>
</template>
</ScriptGoogleMaps>
</template>
placeholder
该插槽用于在加载谷歌地图之前显示占位符图像。默认情况下,这将显示谷歌地图静态 API 的地图图像。
通过提供您自己的占位符插槽,您将禁用默认的占位符图像的使用,并且不会收取静态地图 API 使用费。
<template>
<ScriptGoogleMaps>
<template #placeholder="{ placeholder }">
<img :src="placeholder">
</template>
</ScriptGoogleMaps>
</template>
useScriptGoogleMaps
The useScriptGoogleMaps
可组合组件使您可以对谷歌地图 SDK 进行细粒度的控制。它提供了一种加载谷歌地图 SDK 并以编程方式与之交互的方法。
export function useScriptGoogleMaps<T extends GoogleMapsApi>(_options?: GoogleMapsInput) {}
请遵循 注册表脚本 指南以了解有关高级用法的更多信息。
GoogleMapsApi
export interface GoogleMapsApi {
// @types/google.maps
maps: typeof google.maps
}
示例
加载谷歌地图 SDK 并以编程方式与之交互。
<script setup lang="ts">
/// <reference types="google.maps" />
const { onLoaded } = useScriptGoogleMaps({
apiKey: 'key'
})
const map = ref()
onMounted(() => {
onLoaded(async (instance) => {
const maps = await instance.maps as any as typeof google.maps // upstream google type issue
new maps.Map(map.value, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8
})
// Do something with the map
})
})
</script>
<template>
<div ref="map" />
</template>