Vue项目集成Google Maps报错:PlaceAutocompleteElement不是构造函数
解决:TypeError: google.maps.places.PlaceAutocompleteElement is not a constructor
核心问题分析
你的代码存在两个关键错误:
- 库导入顺序与变量解构完全不匹配,且
Map对象错误地从marker库导入(实际Map属于maps核心库) - 未从
places库中正确解构出PlaceAutocompleteElement,导致无法找到该构造函数
修正步骤
修正库导入逻辑
明确各API所属的库:Map→maps核心库AdvancedMarkerElement→marker库PlaceAutocompleteElement→places库
调整Promise.all的导入顺序与解构对应关系。
启用Places API
确保你的Google Cloud项目已启用Places API,并在加载Maps脚本时传入有效的API密钥(若使用@googlemaps/js-api-loader,需在loader配置中指定密钥)。
修正后的完整代码
<script setup> import { onMounted } from 'vue'; // 假设你已引入@googlemaps/js-api-loader的loader实例 // import { Loader } from '@googlemaps/js-api-loader'; // const loader = new Loader({ apiKey: '你的API密钥', libraries: ['maps', 'marker', 'places'] }); let map; let marker; let infoWindow; const updateInfoWindow = (content, position) => { infoWindow.setContent(content); infoWindow.setPosition(position); infoWindow.open(map); }; const initMap = async () => { const google = await loader.load(); // 正确导入各库并解构所需对象 const [{ Map }, { AdvancedMarkerElement }, { PlaceAutocompleteElement }] = await Promise.all([ google.maps.importLibrary("maps"), google.maps.importLibrary("marker"), google.maps.importLibrary("places"), ]); map = new Map(document.getElementById("map"), { center: { lat: 40.749933, lng: -73.98633 }, zoom: 5, mapTypeControl: false, }); const input = document.createElement("input"); input.id = "pac-input"; input.placeholder = "输入地点"; input.style.padding = "8px"; // 直接使用解构后的PlaceAutocompleteElement,无需@ts-ignore const pac = new PlaceAutocompleteElement({ inputElement: input, }); const card = document.getElementById("pac-card"); card.appendChild(pac.element); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card); // 创建标记和信息窗口 marker = new AdvancedMarkerElement({ map }); infoWindow = new google.maps.InfoWindow({}); // 监听地点选择事件 pac.addListener("gmp-placeselect", async ({ place }) => { await place.fetchFields({ fields: ["displayName", "formattedAddress", "location"], }); if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } const content = ` <div id="infowindow-content"> <span id="place-displayname" class="title">${place.displayName}</span><br /> <span id="place-address">${place.formattedAddress}</span> </div> `; updateInfoWindow(content, place.location); marker.position = place.location; }); }; onMounted(() => { initMap(); }); </script> <template> <div> <div id="pac-card" style="padding: 8px; background: white; border-radius: 4px;"></div> <div id="map" style="width: 100%; height: 600px;"></div> </div> </template>
额外说明
- 若使用TypeScript,确保安装了
@types/google.maps类型定义包,避免类型报错 - 检查API密钥的权限,确保没有设置IP限制或未关联正确的项目
内容的提问来源于stack exchange,提问作者hector404nf
相关产品推荐
相关产品推荐

