news 2026/5/12 1:08:11

Google Maps 多 Marker 场景下 InfoWindow

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Google Maps 多 Marker 场景下 InfoWindow

废话不多说,核心useMap代码如下

import { ElMessage } from 'element-plus' import { useI18n } from 'vue-i18n' const DEFAULT_LAT = 13.752082783751177 const DEFAULT_LNG = 100.49313364056417 export function useMap() { const { t } = useI18n() let map = null // 主坐标点(始终存在) let mainMarker = null // 周边坐标点集合 let aroundMarkers = [] /** * 初始化地图 * @param {HTMLElement} root 地图容器 * @param {Object} point 主坐标点 * @param {Boolean} defaultFlag 是否使用默认坐标 */ function initMap(root, point = {}, defaultFlag = false) { let lat, lng if (defaultFlag) { lat = DEFAULT_LAT lng = DEFAULT_LNG } else { lat = Number(point.latitude) || DEFAULT_LAT lng = Number(point.longitude) || DEFAULT_LNG } map = new google.maps.Map(root, { zoom: 12, center: { lat, lng }, mapTypeControl: false, scaleControl: false, streetViewControl: false, fullscreenControl: false }) // 创建主坐标点 Marker mainMarker = new google.maps.Marker({ map, position: { lat, lng } }) } /** * 渲染周边坐标点(不影响主点) * Marker 与 InfoWindow 在此阶段一并创建 * @param {Array} list 周边点数据 */ function addAroundMarkers(list = []) { if (!map || !Array.isArray(list)) return // 清理旧的周边点 aroundMarkers.forEach(item => { item.marker.setMap(null) }) aroundMarkers = [] list.forEach(item => { const lat = Number(item.latitude) const lng = Number(item.longitude) const title = item.title || '' if (Number.isNaN(lat) || Number.isNaN(lng)) return const marker = new google.maps.Marker({ map, position: { lat, lng }, title }) const infoWindow = new google.maps.InfoWindow({ content: title }) // Marker 点击时显示 InfoWindow marker.addListener('click', () => { infoWindow.open(map, marker) }) aroundMarkers.push({ latitude: lat, longitude: lng, marker, infoWindow }) }) } /** * 点击周边列表项时: * 以主点为参考,展示主点与当前周边点 * 并打开对应的 InfoWindow * @param {Object} point 周边点 */ function focusAroundPoint({ latitude, longitude }) { if (!map || !mainMarker) return const lat = Number(latitude) const lng = Number(longitude) if (Number.isNaN(lat) || Number.isNaN(lng)) { ElMessage.warning(t('位置信息异常')) return } const mainPos = mainMarker.getPosition() const aroundPos = new google.maps.LatLng(lat, lng) const bounds = new google.maps.LatLngBounds() bounds.extend(mainPos) bounds.extend(aroundPos) map.fitBounds(bounds, { top: 60, right: 60, bottom: 60, left: 60 }) // 关闭所有 InfoWindow aroundMarkers.forEach(item => { item.infoWindow.close() }) // 打开目标点的 InfoWindow const target = aroundMarkers.find( item => item.latitude === lat && item.longitude === lng ) if (target) { target.infoWindow.open(map, target.marker) } } /** * 打开 Google Maps(新窗口) * @param {Object} point 坐标点 */ function openMap(point) { if (!point?.latitude || !point?.longitude) { ElMessage.warning(t('位置信息缺失')) return } const lat = Number(point.latitude) const lng = Number(point.longitude) if (Number.isNaN(lat) || Number.isNaN(lng)) { ElMessage.warning(t('位置信息异常')) return } const title = encodeURIComponent(point.title || '') const url = `https://www.google.com/maps/search/?api=1&query=${lat},${lng}(${title})` window.open(url, '_blank') } return { initMap, addAroundMarkers, focusAroundPoint, openMap } }

html

<div class="map-section"> <!-- 地图容器 --> <div class="map-container" ref="mapRef"></div> <!-- 主标题(可点击打开 Google Maps) --> <div class="address-name" @click="openMap(mainPoint)"> {{ mainPoint.title }} </div> <!-- 周边列表 --> <div class="around-list" v-if="aroundList.length"> <div class="around-item" v-for="(item, index) in aroundList" :key="index" @click="focusAroundPoint(item)" > <div class="label">{{ item.title }}</div> </div> </div> <!-- 距离提示 --> <div class="distance-tips"> {{ $t('显示距离') }} </div> </div>

调用示例

<script setup> import { ref, onMounted } from 'vue' import { useMap } from '@/composables/useMap' // 地图容器 const mapRef = ref(null) // 主点(示例数据) const mainPoint = { latitude: 13.75208, longitude: 100.49313, title: 'Main Location' } // 周边点列表(示例数据) const aroundList = [ { latitude: 13.756, longitude: 100.501, title: 'Nearby Point A' }, { latitude: 13.748, longitude: 100.485, title: 'Nearby Point B' } ] // 使用 useMap const { initMap, addAroundMarkers, focusAroundPoint, openMap } = useMap() onMounted(() => { // 初始化地图 initMap(mapRef.value, mainPoint) // 渲染周边 Marker(Marker + InfoWindow 一次性创建) addAroundMarkers(aroundList) }) </script>

结果展示如下图:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 14:21:31

麦角甾醇PEG生物素;Ergosterol-PEG-Biotin的核心价值

试剂基本信息 英文名称&#xff1a;Ergosterol-PEG-Biotin&#xff1b;Ergosterol 中文名称&#xff1a; 麦角甾醇PEG生物素&#xff1b;甲基胆固醇&#xff1b;麦角固醇 纯度&#xff1a;>95% 外观性状&#xff1a;固体 溶解条件&#xff1a;溶于部分有机溶液 供应厂…

作者头像 李华
网站建设 2026/5/10 4:12:59

Java计算机毕设之基于微信小程序的学生成绩管理系统基于小程序的高校班级管理系统设计与实现(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/10 12:22:25

【课程设计/毕业设计】基于微信小程序的企业考勤系统设计与实现基于小程序的企业打卡考勤系统设计与实现【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/10 7:18:55

数据库慢如蜗牛?这 5 个 MySQL 优化技巧让查询快 10 倍!

数据库慢如蜗牛?这5个MySQL优化技巧让查询快10倍! 你是否遇到过这样的情况:程序运行越来越慢,用户抱怨页面加载卡顿,而你却不知道问题出在哪里?别担心,今天我们就来解决这个困扰无数开发者的难题! 😱 一个真实的性能灾难故事 小李是一名刚入职的程序员,他负责维护公…

作者头像 李华