如何在SvelteKit中加载含坐标标记点的基础Google Map
在SvelteKit中实现带多标记点的Google Map
我是Web开发新手,刚接触SvelteKit,想要实现显示带有多个位置标记点的Google Map,这些位置来自坐标数组。我在相关论坛和Reddit上查找过类似帖子,但未能取得任何进展。此前我在使用Vapor和Leaf的项目中成功运行了Google Maps官方示例中的代码,但在SvelteKit中尝试却毫无成效。以下是我在项目默认+page.svelte文件中的尝试代码:
<script> (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))}) ({key: "API_KEY", v: "weekly"}); let map; async function initMap() { const { Map } = await google.maps.importLibrary("maps"); map = new Map(document.getElementById("map"), { center: { lat: -34.397, lng: 150.644 }, zoom: 8, }); } initMap(); </script> <div id="map"></div> <svelte:head> <script async src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <script type="module" src="./index.js"></script> </svelte:head> <style> #map { height: 100%; width: 100%; } </style>
解决方案及优化代码
核心问题分析
- SvelteKit默认SSR模式下,直接在组件脚本中调用DOM相关代码会报错(服务器端无
document对象) - 地图容器高度设置为
100%但父元素无明确高度,导致地图无法显示 - 缺少多标记点的遍历创建逻辑
完整优化代码
<script> import { onMount } from 'svelte'; let map; // 自定义坐标数组,替换成你的数据 const locations = [ { lat: -34.397, lng: 150.644 }, { lat: -34.407, lng: 150.654 }, { lat: -34.387, lng: 150.634 } ]; // 加载Google Maps脚本逻辑保持不变 (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set(), e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a); })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({ key: "你的API_KEY", v: "weekly" }); async function initMap() { const { Map } = await google.maps.importLibrary("maps"); const { Marker } = await google.maps.importLibrary("marker"); // 初始化地图,以第一个坐标为中心 map = new Map(document.getElementById("map"), { center: locations[0], zoom: 10, }); // 遍历坐标数组创建标记点 locations.forEach(location => { new Marker({ position: location, map: map, title: `坐标: ${location.lat}, ${location.lng}` }); }); } // 组件挂载后执行地图初始化,确保DOM已存在 onMount(() => { initMap(); }); </script> <div id="map"></div> <svelte:head> <script async src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> </svelte:head> <style> #map { height: 80vh; /* 用视口高度确保地图有明确显示空间 */ width: 100%; border-radius: 8px; } </style>
关键修改点
- 使用
onMount钩子:确保地图初始化代码只在客户端执行,避免SSR环境下的DOM报错 - 调整地图容器高度:用
80vh替代100%,确保容器有明确的显示高度 - 添加多标记点逻辑:遍历坐标数组,为每个坐标创建Marker并绑定到地图上
- 移除无用的
index.js引用:原代码中该脚本不存在,会导致404错误
内容的提问来源于stack exchange,提问作者KevinF
相关产品推荐
相关产品推荐

