首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >vue3: baidumap using typescript

vue3: baidumap using typescript

作者头像
geovindu
发布2026-06-18 20:44:29
发布2026-06-18 20:44:29
450
举报

项目结构:

代码语言:javascript
复制
<!--
 * @creater: geovindu
 * @since: 2025-05-25 11:32:26
 * @LastAuthor: geovindu
 * @lastTime: 2025-05-25 15:42:02
 * @文件相对于项目的路径: \jsstudy\vamp\src\components\BaiduMapMarker.vue
 * @message: geovindu
 * @IDE: vscode
 * @Development: node.js 20, vuejs3.0
 * @package:
 * @ISO: windows10
 * @database: mysql 8.0 sql server 2019 postgresSQL 16
 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved.
-->
<template>
  <div class="map-container" ref="mapContainer" style="height: 600px;"></div>
</template>
 
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
 
interface Hotel {
  name: string;
  content: string;
  center: string;
  type: number;
  icon: string;
}
 
const props = defineProps<{
  hotels: Hotel[];
  ak: string;
}>();
 
const mapContainer = ref<HTMLElement | null>(null);
let map: BMap.Map | null = null;
let infoWindow: BMap.InfoWindow | null = null;
 
// 加载百度地图API
const loadBMapScript = (ak: string) => {
  return new Promise<void>((resolve, reject) => {
    if (window.BMap) {
      resolve();
      return;
    }
 
    const script = document.createElement('script');
    script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&callback=initBMap`;
    script.async = true;
    script.onload = () => resolve();
    script.onerror = (err) => reject(new Error(`加载百度地图API失败: ${err}`));
    document.head.appendChild(script);
 
    // 定义全局回调函数
    (window as any).initBMap = () => resolve();
  });
};
 
// 初始化地图
const initMap = async () => {
  if (!mapContainer.value || !props.ak) {
    console.error('地图容器或API密钥未设置');
    return;
  }
 
  try {
    console.log('开始加载百度地图API...');
    await loadBMapScript(props.ak);
    console.log('百度地图API加载成功');
     
    // 创建地图实例
    map = new BMap.Map(mapContainer.value);
     
    // 设置中心点(深圳大致位置)
    const centerPoint = new BMap.Point(114.057868, 22.543099);
    map.centerAndZoom(centerPoint, 12);
     
    // 添加地图控件
    map.addControl(new BMap.NavigationControl());
    map.addControl(new BMap.ScaleControl());
    map.addControl(new BMap.OverviewMapControl());
     
    // 初始检查酒店数据
    updateMarkers();
     
    console.log('地图初始化完成');
  } catch (error: any) {
    console.error('加载百度地图失败:', error.message);
  }
};
 
// 更新地图标记
const updateMarkers = () => {
  if (!map) return;
   
  // 清除现有标记
  map.clearOverlays();
   
  console.log('更新酒店标记:', props.hotels);
  if (!props.hotels || props.hotels.length === 0) {
    console.log('酒店数据为空');
    return;
  }
 
  const points: BMap.Point[] = [];
   
  props.hotels.forEach(hotel => {
    const [lng, lat] = hotel.center.split(',').map(Number);
    console.log('添加酒店标记:', hotel.name, '坐标:', lng, lat);
     
    const point = new BMap.Point(lng, lat);
    points.push(point);
     
    // 使用百度地图默认图标
    const icon = new BMap.Icon(
      'https://api.map.baidu.com/images/marker_red_sprite.png',
      new BMap.Size(23, 25)
    );
     
    // 创建标记
    const marker = new BMap.Marker(point, { icon });
    map.addOverlay(marker);
     
    // 添加标签
    const label = new BMap.Label(hotel.name, {
      offset: new BMap.Size(20, -10)
    });
    marker.setLabel(label);
     
    // 添加点击事件
    marker.addEventListener('click', () => {
      showInfoWindow(point, hotel);
    });
  });
   
  // 调整地图视野以显示所有标记
  if (points.length > 0) {
    map.setViewport(points);
  }
};
 
// 显示信息窗口
const showInfoWindow = (point: BMap.Point, hotel: Hotel) => {
  if (!map) return;
   
  // 创建信息窗口
  if (!infoWindow) {
    infoWindow = new BMap.InfoWindow('', {
      width: 250,
      height: 100
    });
  }
   
  // 设置信息窗口内容
  infoWindow.setContent(`
    <div style="font-size: 14px;">
      <h4>${hotel.name}</h4>
      <p>${hotel.content}</p>
    </div>
  `);
   
  // 打开信息窗口
  map.openInfoWindow(infoWindow, point);
};
 
onMounted(() => {
  initMap();
});
 
// 监听酒店数据变化,更新标记
watch(() => props.hotels, () => {
  console.log('酒店数据发生变化,更新标记');
  if (map) {
    updateMarkers();
  }
});
 
onUnmounted(() => {
  // 清理地图资源
  if (map) {
    map.clearOverlays();
    map = null;
  }
  infoWindow = null;
});
</script>
 
<style scoped>
.map-container {
  width: 100%;
  height: 100%;
}
</style>
代码语言:javascript
复制
<!--
 * @creater: geovindu
 * @since: 2025-05-25 11:32:26
 * @LastAuthor: geovindu
 * @lastTime: 2025-05-25 15:50:23
 * @文件相对于项目的路径: \jsstudy\vamp\src\BmapApp.vue
 * @message: geovindu
 * @IDE: vscode
 * @Development: node.js 20, vuejs3.0
 * @package:
 * @ISO: windows10
 * @database: mysql 8.0 sql server 2019 postgresSQL 16
 * Copyright (c) 2025 by geovindu email:geovindu@163.com, All Rights Reserved.
-->
<template>
    <div id="app">
      <h1>深圳酒店百度地图</h1>
      <div v-if="loading" class="loading-message">加载中...</div>
      <div v-else-if="error" class="error-message">
        加载失败: {{ error.message }}
      </div>
      <BaiduMapMarker v-else :hotels="hotels" :ak="baiduMapAK" />
    </div>
  </template>
   
  <script lang="ts" setup>
  import { ref, onMounted } from 'vue';
  import BaiduMapMarker from './components/BaiduMapMarker.vue';
   
  // 百度地图API密钥(确保替换为有效密钥)
  const baiduMapAK = ref('你的KEY');
  const hotels = ref<any[]>([]);
  const loading = ref(true);
  const error = ref<Error | null>(null);
   
  // 从JSON文件加载酒店数据
  const loadHotelData = async () => {
    try {
      const response = await fetch('hotels.json'); // 确保路径正确
      if (!response.ok) {
        throw new Error(`HTTP错误! 状态码: ${response.status}`);
      }
      const data = await response.json();
      hotels.value = data;
      console.log('酒店数据加载成功:', data);
    } catch (err: any) {
      console.error('加载酒店数据失败:', err);
      error.value = err;
    } finally {
      loading.value = false;
    }
  };
   
  onMounted(() => {
    loadHotelData();
  });
  </script>
   
  <style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
    padding: 0 20px;
  }
   
  h1 {
    color: #333;
  }
   
  .loading-message, .error-message {
    padding: 20px;
    margin: 20px;
    background-color: #f5f5f5;
    border-radius: 8px;
  }
   
  .error-message {
    color: #f56c6c;
  }
  </style>

输出:( 用高德的地图经纬度数据,存在误差。)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档